#include <iostream>
#include <ctime>
#include <iomanip>

#include <stm32h7xx_ll_utils.h>
#include "StateBase.hpp"

//StateBase::StateBase(StateNames id, uint32_t timeout)
//	: stateTimeout(timeout)
//	, state_id_(id)
//{
//}


StateBase::StateBase(std::string label, uint32_t timeout) : stateTimeout_min(timeout), stateLabel(label)
{
}

void StateBase::setStateTimeoutAlarm()
{
	tm timeNow;
	time_t time_tNow;
	time_t time_tAlarmTime;
	
	if (this->stateTimeout_min != 0)
	{
		timeNow = RTClock::getDateTimeStruct();
		//convert to epoch based time_t
		time_tNow = mktime(&timeNow);
		time_tAlarmTime = time_tNow + 60 * this->stateTimeout_min;

		//set the RTClock alarm
		bool returnValue = RTClock::setAlarm(RTClock::alarmA, time_tAlarmTime);
	}
	else
	{
		RTClock::clearAlarm(RTClock::alarmA);
		std::cout << "No timeout set for state: " << this->stateLabel << std::endl;
	}
}

void StateBase::enterState()
{
	std::cout << "enterState"  << std::endl;
	StateBase::stdStateEntry();
	enterThisState();
}

StateNames StateBase::exitState(StateEvent event)
{
	std::cout << "exitState"  << std::endl;
	StateBase::stdStateExit(event);
	exitThisState(event);
	std::cout << std::endl;
	LL_mDelay(1000);
}

void StateBase::stdStateEntry()
{
	std::cout << "stdStateEntry"  << std::endl;
	setStateTimeoutAlarm();
	this->enterThisState();
	Logger::logEngLine(true, {stmchEngLogID, RTClock::getDateTimeStamp().data(), this->stateLabel, "stdStateEntry" });
}

StateNames StateBase::stdStateExit(StateEvent event)
{
	std::cout << "stdStateExit"  << std::endl;	
	this->exitThisState(event);
	Logger::logEngLine(true, {stmchEngLogID, RTClock::getDateTimeStampFast().data(), this->stateLabel, "stdStateExit" });
}

void StateBase::setInitialAction(uint8_t actionNum, std::string actionLabel) 
{
	this->previousAction = actionNum;
	this->currentAction = actionNum;
	this->nextAction = actionNum;
	
	std::cout << RTClock::getDateTimeStampFast().data() << '\t' << this->stateLabel << '\t' << "Entry action: " << actionLabel << std::endl;
	
}

uint8_t StateBase::doActionChange(std::string current, std::string next)
{
	this->previousAction = this->currentAction;
	this->currentAction = this->nextAction;
	this->nextAction = this->currentAction;
	
	std::string comment{"Acton change from: "};
	comment.append(current); 
	comment.append(" to: ");
	comment.append(next);
	
	std::cout << comment << std::endl;
	
	Logger::logEngLine(true, {stmchEngLogID, RTClock::getDateTimeStampFast().data(), this->stateLabel, comment });
	
	return this->currentAction;
}

void StateBase::logEngFileHeader()
{
	Logger::logEngLine(false, {stmchEngLogID, "dateTime_Z", "state", "comment" });
	Logger::logEngLine(false, {stmchEngLogID, "text", "text", "text" }); 
}
