#ifndef SERIAL_CONTROL_H
#define SERIAL_CONTROL_H

#include <stdint.h>
#include "main.h"
#include "connector.h"

/* Read-only commands */
#define CMD_GET_INFO            0x01
#define CMD_ISOLATION_STATUS    0x01 /* UART5 isolation block packet */
#define CMD_GET_GBT_STATUS      0x02
#define CMD_GET_CCS_STATUS      0x03
#define CMD_GET_LOG             0x50
#define CMD_GET_LOG_CONTINUE    0x51

/* GBT control commands */
#define CMD_GBT_CC_ENABLE       0x10
#define CMD_GBT_STOP            0x11
#define CMD_GBT_SET_SOC         0x12
#define CMD_GBT_SET_REQUEST     0x13
#define CMD_GBT_SET_VIN         0x18

/* CCS control commands */
#define CMD_CCS_SET_STATE        0x20
#define CMD_CCS_ENABLE_LOAD     0x24

/* Response codes */
#define RESP_SUCCESS            0x12
#define RESP_FAILED             0x13
#define RESP_INVALID            0x14

#define MAX_TX_BUFFER_SIZE      256
#define MAX_RX_BUFFER_SIZE      256
#define CRC32_POLYNOMIAL        ((uint32_t)0xEDB88320)

typedef struct __attribute__((packed)) {
    uint8_t command;
    uint8_t argument_length;
    void *argument;
} ReceivedCommand_t;

typedef enum {
    SC_SOURCE_UART2 = 0,
    SC_SOURCE_UART5 = 1,
} SC_Source_t;

typedef struct __attribute__((packed)) {
    uint8_t isolationStatus;
    uint16_t isolationResistance;
    int16_t voltageHigh;
    int16_t voltageLow;
    int16_t voltageComm;
} IsolationStatusPacket_t;

typedef struct __attribute__((packed)) {
    uint16_t requestedVoltage; /* 1V/bit */
    uint16_t requestedCurrent; /* 0.1A/bit */
} EvSetLimits_t;

typedef struct __attribute__((packed)) {
    uint16_t measuredVoltage; /* 1V/bit */
    uint16_t measuredCurrent; /* 0.1A/bit */
} EvSetMeasured_t;

typedef struct __attribute__((packed)) {
    uint8_t connector_type;      /* 0x01 (GBT) */
    uint16_t requestedVoltage;   /* V */
    uint16_t requestedCurrent;   /* 0.1A/bit */
    uint16_t measuredVoltageSE;  /* V */
    uint16_t measuredCurrentSE;  /* 0.1A/bit */
    uint16_t measuredVoltage;    /* 1V/bit */
    uint16_t measuredCurrent;    /* 0.1A/bit */
    uint8_t cc_enabled;
    uint8_t contactorEnabled;
    CONN_Error_t chargingError;
    uint8_t EvseConnected;
    uint8_t soc;                 /* % */
    uint8_t vin[17];
    uint8_t cc_state;
    uint8_t logs_available;
    CONN_State_t connState;
} GBT_MonitorPacket_t;

typedef struct __attribute__((packed)) {
    uint8_t connector_type;      /* 0x02 (CCS) */
    uint16_t measuredVoltage;    /* 1V/bit */
    uint16_t measuredCurrent;    /* 0.1A/bit */
    uint8_t cp_enabled;
    uint8_t contactorEnabled;
    CONN_Error_t chargingError;
    uint8_t EvseConnected;
    uint8_t soc;                 /* % */
    uint8_t cp_state;            /* A/B/C/D/E/... enum value */
    uint8_t cp_pwm_duty;         /* % */
    CONN_State_t connState;
} CCS_MonitorPacket_t;

typedef struct __attribute__((packed)) {
    uint16_t serialNumber;
    uint8_t boardVersion;
    uint8_t stationType;
    uint16_t fw_version_major;
    uint16_t fw_version_minor;
    uint16_t fw_version_patch;
} InfoPacket_t;

typedef struct SerialControl_t SerialControl_t;
struct SerialControl_t {
    uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
    uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];
    volatile ReceivedCommand_t received_command;
    volatile uint8_t command_ready;
    volatile uint8_t response_pending;
    volatile uint8_t response_code;
    volatile uint32_t tx_tick;
};

void SC_Init(void);
void SC_Task(void);
void SC_SendPacket(const uint8_t *payload, uint16_t payload_len, uint8_t response_code);
void SC_CommandHandler(ReceivedCommand_t *cmd);

extern SerialControl_t serial_control;
extern GBT_MonitorPacket_t gbtMonitorPacket;
extern CCS_MonitorPacket_t ccsMonitorPacket;
extern InfoPacket_t infoPacket;
extern IsolationStatusPacket_t ISO;
extern volatile SC_Source_t g_sc_command_source;

#endif /* SERIAL_CONTROL_H */
