#ifndef _EEPROM_H_
#define _EEPROM_H_

#include <Arduino.h>
#include <Wire.h>
#include <I2C_eeprom.h>

#include "globals.h"
#include "dtc.h"
#include "common.h"
#include "debugger.h"

#define I2C_EE_ADDRESS 0x50
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC64
#define EEPROM_ENDURANCE 1000000

typedef enum
{
  NONE,
  FACTION_1,
  FACTION_2,
  FACTION_3
} factions_t;

typedef struct
{
  uint32_t writeCycleCounter = 0;
  uint32_t faction_1_timer = 0;
  uint32_t faction_2_timer = 0;
  uint32_t faction_3_timer = 0;
  factions_t activeFaction = NONE;
  uint32_t checksum = 0;
} persistenceData_t;

extern persistenceData_t PersistenceData;
typedef enum
{
  BATTERY_UNDEFINED,
  BATTERY_LIPO_2S,
  BATTERY_LIPO_3S
} batteryType_t;

const char BatteryString[][10]{
    "Undefined",
    "LiPo 2S",
    "LiPo 3S"};

const size_t BatteryString_Elements = sizeof(BatteryString) / sizeof(BatteryString[0]);

typedef struct
{
  uint8_t EEPROM_Version;
  batteryType_t batteryType;
  bool active_faction_on_reboot;
  char Faction_1_Name[33];
  char Faction_2_Name[33];
  char Faction_3_Name[33];
  uint32_t checksum;
} configData_t;

extern configData_t ConfigData;

const configData_t ConfigData_defaults = {
    2,                      // EEPROM_Version (incerease this if anything on Layout changes!)
    BATTERY_LIPO_3S,        // batteryType
    false,                  // active_faction_on_reboot
    "FACTION 1",            // Faction_1_Name
    "FACTION 2",            // Faction_2_Name
    "FACTION 3",            // Faction_3_Name
    0                       // checksum
};

const uint16_t startofConfigData = 16;
const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16);

void InitEEPROM();
void EEPROM_Process();
void StoreConfig_EEPROM();
void GetConfig_EEPROM();
void StorePersistence_EEPROM();
void GetPersistence_EEPROM();
void FormatConfig_EEPROM();
void FormatPersistence_EEPROM();
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
void MovePersistencePage_EEPROM(boolean reset);
uint32_t ConfigSanityCheck(bool autocorrect = false);

#endif // _EEPROM_H_