#include "InitPlatformState.hpp"

#include <iostream>
#include <sstream>

//#include <Logger.hpp>
//#include <SDLogger.hpp>
//#include "ConfigData.hpp"
//#include "MissionData.hpp"

InitPlatformState::InitPlatformState(uint32_t timeout) : StateBase{StateNames::initPlatformState, timeout}
{
}

/// We do our initial action in doStateEntry(), which should be some action
/// that generates an event. The rest of the sequence happens in doStateActions in
/// response to the events.
void InitPlatformState::doThisStateEntry()
{
	//ACTION_CHANGE(current_action_, getGPSTime);
}

void InitPlatformState::doThisStateExit(bool timeout)
{
	(void) timeout;
	// TODO: implement exit actions for this state
}

StateNames InitPlatformState::checkEvents(const StateEvent event)
{
	StateNames next_state;
	
	std::cout << "InitPlatformState checking events"  << std::endl;
	if (hitLastAction)
	{
		next_state = StateNames::recoveryState;
	}
	else
	{
		next_state = StateNames::initPlatformState;
	}
	
	return next_state;
}

StateNames InitPlatformState::doStateActions(const StateEvent event)
{
	StateNames next_state;
	hitLastAction = false;

	switch (current_action_)
	{
	case getGPSTime:
		next_state = doGetGPSTime(event);
		break;
	case initLogger:
		next_state = doInitLogger(event);
		break;
	case readConfigFile:
		next_state = doReadConfigFile(event);
		break;
	case readMissionFile:
		next_state = doReadMissionFile(event);
		break;
	case lastAction:
		std::cout << "InitPlatformState action: lastAction" << std::endl;
		hitLastAction = true;
		next_state = StateNames::recoveryState;
		break;
	//default:
		//assert(0); // Unexpected case!
	}

	return next_state;
}

StateNames InitPlatformState::doReadConfigFile(const StateEvent event)
{
	//ConfigData::readConfigData();

	//	return StateNames::recoveryState;
	//ACTION_CHANGE(current_action_, InitPlatformState::readMissionFile);
	return StateNames::initPlatformState;
}

StateNames InitPlatformState::doReadMissionFile(const StateEvent event)
{
	//MissionData::readMissionData();

	//	return StateNames::recoveryState;
	//ACTION_CHANGE(current_action_, InitPlatformState::lastAction);
	return StateNames::initPlatformState;
}

StateNames InitPlatformState::doGetGPSTime(const StateEvent event)
{
//	switch (event.get_message_id())
//	{
//	case ID_EntryAction:
//		std::cout << "[Action: getGPSTime] Entry Event, requesting GPS timestamp" << std::endl;
//		gps_.requestTime();
//		break;
//	case ID_GPSNewTimestampReady:
//		{
//			auto timestamp_event = CONVERT_TO_EVENT_TYPE(event, GPSTimestampReadyEvent);
//
//			std::cout << "[Action: getGPSTime] GPSTimestampReadyEvent received, setting system time" << std::endl;
//
//			setTime(timestamp_event->gpsTimestamp, timestamp_event->captureTimestamp);
//			StateVariables::setMissionStartTime();
//
//			// Now that we have set the system time, we will transition to a new action that initializes the logger
//			// TODO:
//			// In the actual implementation, I would just initialize the logger here, and then move on to the next
//			// action with more substance. The current implementation is a demonstration of moving between
//			// actions and states
//			ACTION_CHANGE(current_action_, initLogger);
//			break;
//		}
//	case ID_GPSCommunicationError:
//		{
////			auto communication_error_event = CONVERT_TO_EVENT_TYPE(event, GPSCommunicationErrorEvent);
////			std::cout << "[Action: getGPSTime] GPSCommunicationErrorEvent: ";
////
////			switch (communication_error_event->error)
////			{
////			case GPSCommunicationErrorEvent::Error::ErrorUnknown:
////				std::cout << "ErrorUnknown";
////				break;
////			case GPSCommunicationErrorEvent::Error::UnexpectedMessage:
////				std::cout << "UnexpectedMessage";
////				break;
////			case GPSCommunicationErrorEvent::Error::Timeout:
////				std::cout << "Timeout";
////				break;
////			case GPSCommunicationErrorEvent::Error::BusError:
////				std::cout << "BusError";
////				break;
////			}
//
//			std::cout << ". Going to request again." << std::endl;
//
//			// An error was received - so we're going to try gettign the timestamp again, until some other
//			// logic is added.
//			// TODO: probably want to check error and take an action here (count error before trying again)
//			gps_.requestTime();
//			break;
//		}
//	default:
//		DEFAULT_UNEXPECTED_EVENT_HANDLER("getGPSTime", event.get_message_id());
//	}
//
//	/// This action never changes the overall system state, so it just returns the current state ID.
//	return state_id_;
}

StateNames InitPlatformState::doInitLogger(const StateEvent event)
{
	/// We default to the current state (no change)
	/// and override if necessary to change state
//	auto next_state = state_id_;
//
//	switch (event.get_message_id())
//	{
//	case ID_EntryAction:
//		{
//			std::cout << "[Action: initLogger] Entry Event, initializing logger" << std::endl;
//
//			// Just for demonstration, capture the profileNum variable to demonstrate the value differences
//			// on a 'fresh boot' (or reset) and 'Wakeup' from Deep Sleep
//			std::cout << "StateVariables::profileNum: " << StateVariables::getProfileNum() << std::endl;
//
//			// Note workaround for demo: initailizing logger with profileNum > 0 currently breaks my system.
//			if (StateVariables::getProfileNum() > 0)
//			{
//				std::cout << "[Action: initLogger] Init with profileNum = 0, as > 0 is currently breaking the demo" << std::endl;
//				auto success = Logger::initialize(0);
//				//assert(success == true);
//			}
//			else
//			{
//				auto success = Logger::initialize(StateVariables::getProfileNum());
//				//assert(success == true);
//			}
//
//			/// If successful, we transition to the next state
//			//next_state = StateNames::secondState;
//			ACTION_CHANGE(current_action_, readConfigFile);
//			break;
//		}
//	default:
//		DEFAULT_UNEXPECTED_EVENT_HANDLER("initLogger", event.get_message_id());
//	}
//	;
//
//	return next_state;
}
