#ifndef MessageHandler_H
#define MessageHandler_H

//===================================
//	Define CP State constant
//===================================
#define CP_STATE_UNKNOWN			0
#define CP_STATE_A					1
#define CP_STATE_B					2
#define CP_STATE_C					3
#define CP_STATE_D					4
#define CP_STATE_E					5
#define CP_STATE_F					6

//==========================================
// Init all Enumeration & Mapping String
//==========================================
#define MACROSTR(k) #k

/*ChargePointErrorCode*/
typedef enum {
	ConnectorLockFailure,
	EVCommunicationError,
	GroundFailure,
	HighTemperature,
	InternalError,
	LocalListConflict,
	NoError,
	OtherError,
	OverCurrentFailure,
	OverVoltage,
	PowerMeterFailure,
	PowerSwitchFailure,
	ReaderFailure,
	ResetFailure,
	UnderVoltage,
	WeakSignal
} ChargePointErrorCode;

/*ChargePointStatus*/
typedef enum {
	Available =0,
	Preparing,
	Charging,
	SuspendedEVSE,
	SuspendedEV,
	Finishing,
	Reserved,
	Unavailable,
	Faulted
}  ChargePointStatus;

/*AvailabilityType*/
typedef enum {
	RegistrationStatus_Accepted,
	RegistrationStatus_Pending,
	RegistrationStatus_Rejected
} RegistrationStatus;

/*AvailabilityType*/
typedef enum {
	Inoperative,
	Operative
} AvailabilityType;

/*AvailabilityStatus*/
typedef enum {
	Accepted,
	Rejected,
	Scheduled
}  AvailabilityStatus;

/*ConfigurationStatus*/
typedef enum {
	ConfigurationStatus_Accepted,
	ConfigurationStatus_Rejected,
	RebootRequired,
	NotSupported
}  ConfigurationStatus;

/*ClearCacheStatus*/
typedef enum {
	ClearCacheStatus_Accepted,
	ClearCacheStatus_Rejected
}  ClearCacheStatus;

/*ChargingProfilePurposeType*/
typedef enum {
	ChargePointMaxProfile,
	TxDefaultProfile,
	TxProfile
}  ChargingProfilePurposeType;

/*ChargingProfileStatus*/
typedef enum {
	ChargingProfileStatus_Accepted,
	ChargingProfileStatus_Rejected,
	ChargingProfileStatus_NotSupported
}  ChargingProfileStatus;

/*ClearChargingProfileStatus*/
typedef enum {
	ClearChargingProfileStatus_Accepted,
	ClearChargingProfileStatus_Unknown
}  ClearChargingProfileStatus;

/*GetCompositeScheduleStatus*/
typedef enum {
	GetCompositeScheduleStatus_Accepted,
	GetCompositeScheduleStatus_Rejected
}  GetCompositeScheduleStatus;

/*ChargingRateUnitType*/
typedef enum {
	ChargingRateUnitType_W,
	ChargingRateUnitType_A
}  ChargingRateUnitType;

/*AuthorizationStatus*/
typedef enum {
	AuthorizationStatus_Accepted ,
	AuthorizationStatus_Blocked ,
	AuthorizationStatus_Expired ,
	AuthorizationStatus_Invalid ,
	AuthorizationStatus_ConcurrentTx
}  AuthorizationStatus;

/*UpdateType*/
typedef enum {
	Differential  ,
	Full
}  UpdateType;

/*UpdateStatus*/
typedef enum {
	UpdateStatus_Accepted   ,
	UpdateStatus_Failed ,
	UpdateStatus_NotSupported ,
	UpdateStatus_VersionMismatch
}  UpdateStatus;

/*RemoteStartStopStatus*/
typedef enum {
	RemoteStartStopStatus_Accepted,
	RemoteStartStopStatus_Rejected

}  RemoteStartStopStatus;

/*ReservationStatus*/
typedef enum {
	ReservationStatus_Accepted,
	ReservationStatus_Faulted,
	ReservationStatus_Occupied,
	ReservationStatus_Rejected,
	ReservationStatus_Unavailable

}  ReservationStatus;

/*ResetType*/
typedef enum {
	Hard,
	Soft
}  ResetType;

/*ResetStatus*/
typedef enum {
	ResetStatus_Accepted,
	ResetStatus_Rejected
}  ResetStatus;

/*DiagnosticsStatus*/
typedef enum {
	DiagnosticsStatus_Idle,
	DiagnosticsStatus_Uploaded,
	DiagnosticsStatus_UploadFailed,
	DiagnosticsStatus_Uploading
}  DiagnosticsStatus;

/*FirmwareStatus*/
typedef enum {
	FirmwareStatus_Downloaded,
	FirmwareStatus_DownloadFailed,
	FirmwareStatus_Downloading,
	FirmwareStatus_Idle,
	FirmwareStatus_InstallationFailed,
	FirmwareStatus_Installing,
	FirmwareStatus_Installed
}  FirmwareStatus;

/*MessageTrigger*/
typedef enum {
	BootNotification,
	DiagnosticsStatusNotification,
	FirmwareStatusNotification,
	Heartbeat,
	MeterValues,
	StatusNotification
}   MessageTrigger;

/*TriggerMessageStatus*/
typedef enum {
	TriggerMessageStatus_Accepted ,
	TriggerMessageStatus_Rejected ,
	TriggerMessageStatus_NotImplemented
}   TriggerMessageStatus;

/*UnlockStatus*/
typedef enum {
	Unlocked,
	UnlockFailed,
	UnlockStatus_NotSupported
}   UnlockStatus;

/*StopTransactionReason*/
typedef enum {
	EmergencyStop,
	EVDisconnected,
	HardReset,
	Local,
	Other,
	PowerLoss,
	Reboot,
	Remote,
	SoftReset,
	UnlockCommand,
	DeAuthorized
}   StopTransactionReason;

/*CancelReservationStatus*/
typedef enum {
	CancelReservationStatus_Accepted,
	CancelReservationStatus_Rejected
}   CancelReservationStatus;

/*ReadingContext*/
typedef enum {
	ReadingContext_Interruption_Begin,
	ReadingContext_Interruption_End,
	ReadingContext_Other,
	ReadingContext_Sample_Clock,
	ReadingContext_Sample_Periodic ,
	ReadingContext_Transaction_Begin ,
	ReadingContext_Transaction_End,
	ReadingContext_Trigger
}  ReadingContext;

/*ValueFormat*/
typedef enum {
	Raw,
	SignedData
}  ValueFormat;

/*Measurand*/
typedef enum {
	Current_Export ,
	Current_Import,
	Current_Offered,
	Energy_Active_Export_Register,
	Energy_Active_Import_Register,
	Energy_Reactive_Export_Register,
	Energy_Reactive_Import_Register,
	Energy_Active_Export_Interval,
	Energy_Active_Import_Interval,
	Energy_Reactive_Export_Interval,
	Energy_Reactive_Import_Interval,
	Frequency,
	Power_Active_Export ,
	Power_Active_Import,
	Power_Factor,
	Power_Offered,
	Power_Reactive_Export,
	Power_Reactive_Import,
	RPM,
	SoC,
	Temperature ,
	Voltage
}  Measurand;

/*Location*/
typedef enum {
	Location_Body,
	Location_Cable,
	Location_EV,
	Location_Inlet ,
	Location_Outlet
}  Location;

/*Phase*/
typedef enum {
	L1,
	L2,
	L3,
	N,
	L1_N,
	L2_N,
	L3_N,
	L1_L2,
	L2_L3,
	L3_L1
}  Phase;

/*UnitOfMeasure*/
typedef enum {
	UnitOfMeasure_Wh,
	UnitOfMeasure_kWh ,
	UnitOfMeasure_varh ,
	UnitOfMeasure_kvarh ,
	UnitOfMeasure_W ,
	UnitOfMeasure_kW ,
	UnitOfMeasure_VA ,
	UnitOfMeasure_kVA ,
	UnitOfMeasure_var ,
	UnitOfMeasure_kvar ,
	UnitOfMeasure_A ,
	UnitOfMeasure_V ,
	UnitOfMeasure_Celsius ,
	UnitOfMeasure_Fahrenheit ,
	UnitOfMeasure_K ,
	UnitOfMeasure_Percent

}  UnitOfMeasure;

/*Configuration enum*/
enum LocalAuthListManagementProfile{
	LocalAuthListEnabled=0,
	LocalAuthListMaxLength,
	SendLocalListMaxLength,
	_LocalAuthListManagementProfile_CNT
};

enum ReservationProfile{
	ReserveConnectorZeroSupported
};

enum SmartChargingProfile{
	ChargeProfileMaxStackLevel,
	ChargingScheduleAllowedChargingRateUnit,
	ChargingScheduleMaxPeriods,
	ConnectorSwitch3to1PhaseSupported,
	MaxChargingProfilesInstalled
};

enum ChargerSystemStatus{
	ChargerSystemStatus_Booting,
	ChargerSystemStatus_Idle,
	ChargerSystemStatus_Authorizing,
	ChargerSystemStatus_Preparing,
	ChargerSystemStatus_Charging,
	ChargerSystemStatus_Terminating,
	ChargerSystemStatus_Alarm,
	ChargerSystemStatus_Fault
};

enum GetConfigurationKey {
	GetConfiguration_AllowOfflineTxForUnknownId=0,
	GetConfiguration_AuthorizationCacheEnabled,
	GetConfiguration_AuthorizeRemoteTxRequests,
	GetConfiguration_BlinkRepeat,
	GetConfiguration_ClockAlignedDataInterval,
	GetConfiguration_ConnectionTimeOut,
	GetConfiguration_GetConfigurationMaxKeys,
	GetConfiguration_HeartbeatInterval,
	GetConfiguration_LightIntensity,
	GetConfiguration_LocalAuthorizeOffline,
	GetConfiguration_LocalPreAuthorize,
	GetConfiguration_MaxEnergyOnInvalidId,
	GetConfiguration_MeterValuesAlignedData,
	GetConfiguration_MeterValuesAlignedDataMaxLength,
	GetConfiguration_MeterValuesSampledData,
	GetConfiguration_MeterValuesSampledDataMaxLength,
	GetConfiguration_MeterValueSampleInterval,
	GetConfiguration_MinimumStatusDuration,
	GetConfiguration_NumberOfConnectors,
	GetConfiguration_ResetRetries,
	GetConfiguration_ConnectorPhaseRotation,
	GetConfiguration_ConnectorPhaseRotationMaxLength,
	GetConfiguration_StopTransactionOnEVSideDisconnect,
	GetConfiguration_StopTransactionOnInvalidId,
	GetConfiguration_StopTxnAlignedData,
	GetConfiguration_StopTxnAlignedDataMaxLength,
	GetConfiguration_StopTxnSampledData,
	GetConfiguration_StopTxnSampledDataMaxLength,
	GetConfiguration_SupportedFeatureProfiles,
	GetConfiguration_SupportedFeatureProfilesMaxLength,
	GetConfiguration_TransactionMessageAttempts,
	GetConfiguration_TransactionMessageRetryInterval,
	GetConfiguration_UnlockConnectorOnEVSideDisconnect,
	GetConfiguration_WebSocketPingInterval,
	GetConfiguration_QueueOffLineMeterValues,
	GetConfiguration_AuthorizationKey,
	GetConfiguration_SecurityProfile,
	GetConfiguration_DefaultPrice,
	GetConfiguration_CustomDisplayCostAndPrice,
	GetConfiguration_CustomIdleFeeAfterStop,
	GetConfiguration_SystemUptimeSec,
	GetConfiguration_FreeVend,
	GetConfiguration_FreeVendIdtag,
	GetConfiguration_OcppServer,
	GetConfiguration_MaintainServer,
	GetConfiguration_StatusNotificationPeriodically,
	GetConfiguration_StatusNotificationInterval,
	GetConfiguration_isEnableLocalPowerSharing,
	GetConfiguration_PowerSharingServerIP,
	GetConfiguration_EVCCID_PREFIX,
	GetConfiguration_OffLineMaxChargingPower,
	GetConfiguration_LocalAuthListEnabled,
	GetConfiguration_LocalAuthListMaxLength,
	GetConfiguration_SendLocalListMaxLength,
	GetConfiguration_ReserveConnectorZeroSupported,
	GetConfiguration_ChargeProfileMaxStackLevel,
	GetConfiguration_ChargingScheduleAllowedChargingRateUnit,
	GetConfiguration_ChargingScheduleMaxPeriods,
	GetConfiguration_ConnectorSwitch3to1PhaseSupported,
	GetConfiguration_MaxChargingProfilesInstalled,
	GetConfiguration_ConfigurationVersion,
	GetConfiguration_CharingProfileRefreshInterval,
	GetConfiguration_OcppSoftwareVersion,
	_GetConfiguration_CNT
};

enum FIRMWARE_NOTIFICATION_STATUS
{
	FIRMWARE_STATUS_DOWNLOADED = 0,
	FIRMWARE_STATUS_DOWNLOAD_FAILED = 1,
	FIRMWARE_STATUS_DOWNLOADING = 2,
	FIRMWARE_STATUS_IDLE = 3,
	FIRMWARE_STATUS_INSTALLATION_FAILED =4,
	FIRMWARE_STATUS_INSTALLING = 5,
	FIRMWARE_STATUS_INSTALLED = 6
};

enum DIAGNOSTIC_NOTIFICATION_STATUS
{
	DIAGNOSTIC_STATUS_IDLE = 0,
	DIAGNOSTIC_STATUS_UPLOADED = 1,
	DIAGNOSTIC_STATUS_UPLOAD_FAIL = 2,
	DIAGNOSTIC_STATUS_UPLOADING =3
};

struct StructPeriod
{
	int		StartPeriod;
	float 	Limit;//0.1;
	int		NumberPhases;
};

struct StructProfile
{
	int	Duration;
	int TotalPeriod;
	struct StructPeriod	Period[10];
};

//===============================================
// Common routine
//===============================================
int initialConfigurationTable(void);
void StoreConfigurationTable(void);
void GetStartTransactionIdTag(int gun_index);

//==========================================
// send request routine
//==========================================
int sendAuthorizeRequest(int gun_index);
int sendBootNotificationRequest(void);
int sendDataTransferRequest(int gun_index);
int sendUnplugByDataTransferRequest(int gun_index);
int sendFirmwareVersionByDataTransfer(void);
int sendDiagnosticsStatusNotificationRequest(char *status);
int sendFirmwareStatusNotificationRequest(char *status);
int sendHeartbeatRequest(int gun_index);
int sendStartTransactionRequest(int gun_index);
int sendStatusNotificationRequest(int gun_index);
int sendStopTransactionRequest(int gun_index);
int sendMeterValuesRequest(int gun_index, ReadingContext dataType);

int sendLogStatusNotificationRequest(char *status);
int sendSecurityEventNotificationRequest();
int sendSignCertificateRequest();
int sendSignedFirmwareStatusNotificationRequest(char *status);

//==========================================
// send confirm routine
//==========================================
int sendCancelReservationConfirmation(char *uuid,char *payload);
int sendChangeAvailabilityConfirmation(char *uuid,char *payload);
int sendChangeConfigurationConfirmation(char *uuid,char *payload);
int sendClearCacheConfirmation(char *uuid,char *payload);
int sendClearChargingProfileConfirmation(char *uuid,char *payload);
int sendDataTransferConfirmation(char *uuid,char *payload);
int sendGetCompositeScheduleConfirmation(char *uuid,char *payload, int connectorIdInt,int nPeriod);
int sendGetConfigurationConfirmation(char *uuid);
int sendGetDiagnosticsConfirmation(char *uuid,char *payload);
int sendGetLocalListVersionConfirmation(char *uuid,char *payload);
int sendRemoteStartConfirmation(char *uuid,char *payload);
int sendRemoteStopTransactionConfirmation(char *uuid,char *payload);
int sendReserveNowTransactionConfirmation(char *uuid,char *payload);
int sendResetConfirmation(char *uuid,char *payload);
int sendSendLocalListConfirmation(char *uuid,char *payload);
int sendSetChargingProfileConfirmation(char *uuid,char *payload);
int sendTriggerMessageConfirmation(char *uuid,char *payload);
int sendUnlockConnectorConfirmation(char *uuid,char *payload);
int sendUpdateFirmwareConfirmation(char *uuid);

int sendCertificateSignedConfirmation(char *uuid);
int sendDeleteCertificateConfirmation(char *uuid);
int sendExtendedTriggerMessageConfirmation(char *uuid);
int sendGetInstalledCertificateIdsConfirmation(char *uuid);
int sendGetLogConfirmation(char *uuid);
int sendInstallCertificateConfirmation(char *uuid);
int sendSignedUpdateFirmwareConfirmation(char *uuid);

int sendUnknownConfirmation(char *uuid);

//==========================================
// send CallError routine
//==========================================
void SendCallError(char *uniqueId, char *action, char *errorCode, char *errorDescription);

//==========================================
// Handle server request routine  Start
//==========================================
int handleCancelReservationRequest(char *uuid, char *payload);
int handleChangeAvailabilityRequest(char *uuid, char *payload);
int handleChangeConfigurationRequest(char *uuid, char *payload);
int handleClearCacheRequest(char *uuid, char *payload);
int handleClearChargingProfileRequest(char *uuid, char *payload);
int handleDataTransferRequest(char *uuid, char *payload);
int handleGetCompositeScheduleRequest(char *uuid, char *payload);
int handleGetConfigurationRequest(char *uuid, char *payload);
int handleGetDiagnosticsRequest(char *uuid, char *payload);
int handleGetLocalListVersionRequest(char *uuid, char *payload);
int handleRemoteStartRequest(char *uuid, char *payload);
int handleRemoteStopTransactionRequest(char *uuid, char *payload);
int handleReserveNowTransactionRequest(char *uuid, char *payload);
int handleResetRequest(char *uuid, char *payload);
int handleSendLocalListRequest(char *uuid, char *payload);
int handleSetChargingProfileRequest(char *uuid, char *payload);
int handleTriggerMessageRequest(char *uuid, char *payload);
int handleUnlockConnectorRequest(char *uuid, char *payload);
int handleUpdateFirmwareRequest(char *uuid, char *payload);
int handleCertificateSignedRequest(char *uuid, char *payload);
int handleDeleteCertificateRequest(char *uuid, char *payload);
int handleExtendedTriggerMessageRequest(char *uuid, char *payload);
int handleGetInstalledCertificateIdsRequest(char *uuid, char *payload);
int handleGetLogRequest(char *uuid, char *payload);
int handleInstallCertificateRequest(char *uuid, char *payload);
int handleSignedUpdateFirmwareRequest(char *uuid, char *payload);
int handleUnknownRequest(char *uuid, char *payload);

void handleAuthorizeResponse(char *payload, int gun_index);
void handleBootNotificationResponse(char *payload, int gun_index);
void handleDataTransferResponse(char *payload, int gun_index);
void handleDiagnosticsStatusNotificationResponse(char *payload, int gun_index);
void handleFirmwareStatusNotificationResponse(char *payload, int gun_index);
void handleHeartbeatResponse(char *payload, int gun_index);
void handleMeterValuesResponse(char *payload, int gun_index);
void handleStartTransactionResponse(char *payload, int gun_index);
void handleStatusNotificationResponse(char *payload, int gun_index);
void handleStopTransactionnResponse(char *payload, int gun_index);
void handleLogStatusNotificationResponse(char *payload, int gun_index);
void handleSecurityEventNotificationResponse(char *payload, int gun_index);
void handleSignCertificateResponse(char *payload, int gun_index);
void handleSignedFirmwareStatusNotificationResponse(char *payload, int gun_index);

//==========================================
// Handle Error routine
//==========================================
void handleError(char *id, char *errorCode, char *errorDescription,char *payload);

//===============================================
// Common routine
//===============================================
void getKeyValue(char *keyReq);
int  setKeyValue(char *key, char *value);
int updateSetting(char *key, char *value);
int httpDownLoadFile(char *location, char *path, char *filename,char *url);
int ftpDownLoadFile(char *location, char *user, char *password, int port, char *path, char *filename,char *url);
void *UpdateFirmwareProcess(void* data);
void* GetDiagnosticsProcess(void* data);
int httpUploadFile(char *location, char *path, char *filename,char *url);
int sftpDownLoadFile(char *location, char *user, int port, char *path, char *filename,char *url);
int ftpUploadFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename);
void LWS_Send(char * str);
void LWS_SendNow(char * str);
extern int queue_operation(int type, char *frontUUID, char *frontData);
int GetOcppServerURL();
int GetOcppPath();
int GetOcppPort();
int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction);
int GetStartTransactionId(int gun_index);
void SetTransactionIdZero(int transactionId);
void GetChargingProfileRequest(int gunindex);
void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[]);
void splitstring(char *src,const char *separator,char **dest,int *num);
int GetWebSocketPingInterval(void);
int GetInternetConn(void);
int GetBackendConnectionTimeout(void);
int isConnectorInitMode(int gun_index);
void refreshProcDogTimer();
int GetServerSign(void);
void SetServerSign(int value);
int GetBootNotificationInterval(void);
void InitialSystemValue(void);
void checkTempStopTransaction(int gun_index);
void storeTempStopTransaction(int gun_index);

//===============================================
// sqlite related routine
//===============================================
int SettingChargingRecord(int target, int transactionId);
int addBuff(int gun_idx, int user_id, int cmd_sn);
int OCPP_cleanLocalCache();
int OCPP_addLocalCache(char *idTag, char *parentTage, char *expiryDate, char *status);
void OCPP_getIdTagFromLocalCache(char idTag[]);
void OCPP_getListVerion();
int OCPP_cleanLocalList();
int OCPP_addLocalList(int version, char *idTag, char *parentTage, char *expiryDate, char *status);
void OCPP_getIdTagFromLocalList(char idTag[]);
void OCPP_deleteIdTagFromLocalList(char idTag[]);


#endif