#include "ETH_Driver.h"

namespace drivers
{

    Ethernet::Ethernet(const std::string hostname) : m_hostname(hostname), m_connected(false), m_localIP(IPAddress()), m_udp(NetworkUDP()), m_timeClient(m_udp)
    {
        SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
        ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI);

        m_timeClient = std::move(NTPClient(m_udp, "pool.ntp.org", 0, 3600)); // NTP server, time offset in seconds, update interval
        m_timeClient.begin();
    }

    Ethernet::~Ethernet()
    {
        m_timeClient.end();
        ETH.end();
        SPI.end();
    }

    const bool Ethernet::getNtpTime(time_t &time)
    {
        if (m_connected && m_timeClient.update())
        {
            time = m_timeClient.getEpochTime();
            LOG_DEBUG("Epoch Time:", (long)time);
            return true;
        }
        return false;
    }

    const bool Ethernet::isConnected()
    {
        return m_connected;
    }

    void Ethernet::onEvent(arduino_event_id_t event, arduino_event_info_t info)
    {
        switch (event)
        {
        case ARDUINO_EVENT_ETH_START:
            ETH.setHostname("waveshare-esp32s3");
            break;
        case ARDUINO_EVENT_ETH_CONNECTED:
            LOG_INFO("ETH Connected");
            break;
        case ARDUINO_EVENT_ETH_GOT_IP:
            m_localIP = ETH.localIP();
            LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Got IP:", m_localIP.toString().c_str());
            LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Gateway:", ETH.gatewayIP().toString().c_str());
            LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Netmask:", ETH.subnetMask().toString().c_str());
            m_connected = true;
            break;
        case ARDUINO_EVENT_ETH_LOST_IP:
            LOG_INFO("ETH Lost IP");
            m_connected = false;
            break;
        case ARDUINO_EVENT_ETH_DISCONNECTED:
            LOG_INFO("ETH Disconnected");
            m_connected = false;
            break;
        case ARDUINO_EVENT_ETH_STOP:
            LOG_INFO("ETH Stopped");
            m_connected = false;
            break;
        default:
            break;
        }
    }

}