#include "SAB.h"

SAB::SAB() : _sdCardManager(_boardConfig.getSPI_SDCard_cs(), _boardConfig.getSPISpeed()), 
_display(_boardConfig.getScreenWidth(),_boardConfig.getScreenHeight(), &Wire),
_screenManager(_display, &_sdCardManager),
_connectivityManager(_sdCardManager), 
_webServerManager(_sdCardManager),
_ftpServer(&_sdCardManager, 21, "ESP8266", "12345678", 10),
_otaManager(_sdCardManager, _boardConfig),
_dbWSServer(81),
_pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire),
_ioManager(_pcf),
_taskSchedulerManager(_rtcManager)
{
  initCommonConfig();
}

SAB::SAB(const BoardConfig boardConfig, const unsigned int ftpServerPort) : _boardConfig(boardConfig),
_sdCardManager(_boardConfig.getSPI_SDCard_cs(), _boardConfig.getSPISpeed()),
_display(_boardConfig.getScreenWidth(), _boardConfig.getScreenHeight(), &Wire),
_screenManager(_display, &_sdCardManager), 
_connectivityManager(_sdCardManager), 
_webServerManager(_sdCardManager),
_ftpServer(&_sdCardManager, ftpServerPort, "ESP8266", "12345678", 10),
_otaManager(_sdCardManager, _boardConfig),
_dbWSServer(81),
_pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire), 
_ioManager(_pcf),
_taskSchedulerManager(_rtcManager)
{
  initCommonConfig();
}

void SAB::initCommonConfig()
{
  //We set the gpio up
  initGPIO();
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
  Serial.println();
  delay(1000);
  
  //We initialize the pins for the  I2C communication
  Wire.begin(_boardConfig.getI2C_sda(), _boardConfig.getI2C_scl());
  if(!_rtc.begin())
    _error |= RTC_BEGIN_ERR;
  else
  {
    _rtcManager.setDateTime(_rtc.now());
  }

  if(!_display.begin(SSD1306_SWITCHCAPVCC, _boardConfig.getI2C_screenAddress()))
  { 
    _error |= DISP_BEGIN_ERR;
  }

  if(!_sdCardManager.mountSD())
  { 
    _error |= SDCARD_INIT_ERR;
    Serial.printf_P(PSTR("Failed to init SDCard :\n\tSpeed -> %u\n\tCS Pin -> %u\n"), 
    _boardConfig.getSPISpeed(),
    _boardConfig.getSPI_SDCard_cs());
  }

  _screenManager.init();
  if(!_connectivityManager.connect()){ _error |= CONNECT_ERR;}
  if(!_pcf.begin()){_error |= IO_INIT_ERR;}
  if(!_otaManager.init()){_error |= OTAMAN_INIT_ERR;}
  if(!_webServerManager.init()){_error |= WEBSRVMAN_INIT_ERR;}

  //We set the different servers :
  _ftpServer.setFTPDir(FTP_DIR);
  //We start the servers
  _dbWSServer.begin();
  _ftpServer.enableTCPKeepAlive(15,5,5);
  _ftpServer.start();
}

void SAB::initGPIO()
{
}

ScreenManager& SAB::getScreenManager()
{
  return _screenManager;
}

RtcManager& SAB::getRtcManager()
{
  return _rtcManager;
}

RTC_DS3231& SAB::getRTC_DS3231()
{
  return _rtc;
}

SDCardManager& SAB::getSdCardManager()
{
  return _sdCardManager;
}

ConnectivityManager& SAB::getConnectivityManager()
{
  return _connectivityManager;
}

WEBServerManager& SAB::getWebServerManager()
{
  return _webServerManager;
}

FTPServer<FTPClient>& SAB::getFtpServer()
{
  return _ftpServer;
}

OTAManager& SAB::getOTAManager()
{
  return _otaManager;
}

IOManager& SAB::getIOManager()
{
  return _ioManager;
}

TaskSchedulerManager& SAB::getTaskSchedulerManager()
{
  return _taskSchedulerManager;
}

PowerManager& SAB::getPowerManager()
{
  return _powerManager;
}

TimeSpan SAB::getUpTime() const
{
  return TimeSpan(millis() / 1000);
}

BoardConfig SAB::getBoardConfig() const
{
  return _boardConfig;
}

const char *SAB::getSoftVersion() const
{
  return SOFT_VERSION;
}

uint8_t SAB::getError() const
{
  return _error;
}

void SAB::run()
{
  _webServerManager.getWEBServer().run();
  _ftpServer.run();
  _taskSchedulerManager.run();
  _screenManager.run();
  _dbWSServer.loop();
}
