#ifndef SAB_H
#define SAB_H

#include "BoardConfig.h"
#include "RtcManager.h"
#include "ScreenManager.h"
#include "SDCardManager.h"
#include "ConnectivityManager.h"
#include "WEBServerManager.h"
#include "FTPClient.h" //includes FTPServer internally
#include "DashboardWSServer.h"
#include "IOManager.h"
#include "TaskSchedulerManager.h"
#include "PowerManager.h"
#include "OTAManager.h"
#include "versions.h"
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#include <SD.h>

class SAB
{
  public:
    enum Error {RTC_BEGIN_ERR = 1 << 0, DISP_BEGIN_ERR = 1 << 1, SDCARD_INIT_ERR = 1 << 2, IO_INIT_ERR = 1 << 3, CONNECT_ERR = 1 << 4, OTAMAN_INIT_ERR = 1 << 5, WEBSRVMAN_INIT_ERR = 1 << 6};
  
    SAB();
    SAB(const BoardConfig boardConfig, const unsigned int ftpServerPort = 21);
    ~SAB()
    {
    }
    
    ScreenManager& getScreenManager();
    RtcManager& getRtcManager();
    RTC_DS3231& getRTC_DS3231();
    SDCardManager& getSdCardManager();
    ConnectivityManager& getConnectivityManager();
    WEBServerManager& getWebServerManager();
    FTPServer<FTPClient>& getFtpServer();
    OTAManager& getOTAManager();
    IOManager& getIOManager();
    TaskSchedulerManager& getTaskSchedulerManager();
    PowerManager& getPowerManager();
    TimeSpan getUpTime() const;
    BoardConfig getBoardConfig() const;
    void run();
    
    const char *getSoftVersion() const;
    uint8_t getError() const;
  private:
    void initGPIO();
    void initCommonConfig();
    
    const BoardConfig _boardConfig;
    SDCardManager _sdCardManager;
    Adafruit_SSD1306 _display;
    ScreenManager _screenManager;
    RTC_DS3231 _rtc;
    RtcManager _rtcManager;
    ConnectivityManager _connectivityManager;
    WEBServerManager _webServerManager;
    FTPServer<FTPClient> _ftpServer;
    OTAManager _otaManager;
    DashboardWSServer _dbWSServer;
    PCF8574 _pcf;
    IOManager _ioManager;
    TaskSchedulerManager _taskSchedulerManager;
    PowerManager _powerManager;
    uint8_t _error = NO_ERROR;
};

#endif //SAB_H
