#include "sol_context.hpp"

#include "main.hpp"
#include "sd_event_loop.hpp"
#include "sol_manager.hpp"

#include <phosphor-logging/log.hpp>

namespace sol
{
using namespace phosphor::logging;

Context::Context(std::shared_ptr<boost::asio::io_context> io,
                 uint8_t maxRetryCount, uint8_t sendThreshold, uint8_t instance,
                 session::SessionID sessionID) :
    accumulateTimer(*io),
    retryTimer(*io), maxRetryCount(maxRetryCount), retryCounter(maxRetryCount),
    sendThreshold(sendThreshold), payloadInstance(instance),
    sessionID(sessionID)
{
    session = std::get<session::Manager&>(singletonPool).getSession(sessionID);
    enableAccumulateTimer(true);
}

void Context::enableAccumulateTimer(bool enable)
{
    // fetch the timeout from the SOL manager
    std::chrono::microseconds interval =
        std::get<sol::Manager&>(singletonPool).accumulateInterval;
    if (enable)
    {
        accumulateTimer.expires_after(interval);
        accumulateTimer.async_wait([this](const boost::system::error_code& ec) {
            if (!ec)
            {
                charAccTimerHandler();
            }
        });
    }
    else
    {
        accumulateTimer.cancel();
    }
}

void Context::enableRetryTimer(bool enable)
{
    if (enable)
    {
        // fetch the timeout from the SOL manager
        std::chrono::microseconds interval =
            std::get<sol::Manager&>(singletonPool).retryInterval;
        retryTimer.expires_after(interval);
        retryTimer.async_wait([this](const boost::system::error_code& ec) {
            if (!ec)
            {
                retryTimerHandler();
            }
        });
    }
    else
    {
        retryTimer.cancel();
    }
}

void Context::processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum,
                                    uint8_t count, bool status,
                                    const std::vector<uint8_t>& input)
{
    uint8_t respAckSeqNum = 0;
    uint8_t acceptedCount = 0;
    auto ack = false;

    /*
     * Check if the Inbound sequence number is same as the expected one.
     * If the Packet Sequence Number is 0, it is an ACK-Only packet. Multiple
     * outstanding sequence numbers are not supported in this version of the SOL
     * specification. Retried packets use the same sequence number as the first
     * packet.
     */
    if (seqNum && (seqNum != seqNums.get(true)))
    {
        log<level::INFO>("Out of sequence SOL packet - packet is dropped");
        return;
    }

    /*
     * Check if the expected ACK/NACK sequence number is same as the
     * ACK/NACK sequence number in the packet. If packet ACK/NACK sequence
     * number is 0, then it is an informational packet. No request packet being
     * ACK'd or NACK'd.
     */
    if (ackSeqNum && (ackSeqNum != seqNums.get(false)))
    {
        log<level::INFO>("Out of sequence ack number - SOL packet is dropped");
        return;
    }

    /*
     * Retry the SOL payload packet in the following conditions:
     *
     * a) NACK in Operation/Status
     * b) Accepted Character Count does not match with the sent out SOL payload
     * c) Non-zero Packet ACK/NACK Sequence Number
     */
    if (status || ((count != expectedCharCount) && ackSeqNum))
    {
        resendPayload(noClear);
        enableRetryTimer(false);
        enableRetryTimer(true);
        return;
    }
    /*
     * Clear the sent data once the acknowledgment sequence number matches
     * and the expected character count matches.
     */
    else if ((count == expectedCharCount) && ackSeqNum)
    {
        // Clear the Host Console Buffer
        std::get<sol::Manager&>(singletonPool).dataBuffer.erase(count);

        // Once it is acknowledged stop the retry interval timer
        enableRetryTimer(false);

        retryCounter = maxRetryCount;
        expectedCharCount = 0;
        payloadCache.clear();
    }

    // Write character data to the Host Console
    if (!input.empty() && seqNum)
    {
        auto rc =
            std::get<sol::Manager&>(singletonPool).writeConsoleSocket(input);
        if (rc)
        {
            log<level::ERR>("Writing to console socket descriptor failed");
            ack = true;
        }
        else
        {
            respAckSeqNum = seqNum;
            ack = false;
            acceptedCount = input.size();
        }
    }
    /*
     * SOL payload with no character data and valid sequence number can be used
     * as method to keep the SOL session active.
     */
    else if (input.empty() && seqNum)
    {
        respAckSeqNum = seqNum;
    }

    if (seqNum != 0)
    {
        seqNums.incInboundSeqNum();
        prepareResponse(respAckSeqNum, acceptedCount, ack);
    }
    else
    {
        enableAccumulateTimer(true);
    }
}

void Context::prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack)
{
    auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.size();

    /* Sent a ACK only response */
    if (payloadCache.size() != 0 || (bufferSize < sendThreshold))
    {
        enableAccumulateTimer(true);

        std::vector<uint8_t> outPayload(sizeof(Payload));
        auto response = reinterpret_cast<Payload*>(outPayload.data());
        response->packetSeqNum = 0;
        response->packetAckSeqNum = ackSeqNum;
        response->acceptedCharCount = count;
        response->outOperation.ack = ack;
        sendPayload(outPayload);
        return;
    }

    auto readSize = std::min(bufferSize, MAX_PAYLOAD_SIZE);
    payloadCache.resize(sizeof(Payload) + readSize);
    auto response = reinterpret_cast<Payload*>(payloadCache.data());
    response->packetAckSeqNum = ackSeqNum;
    response->acceptedCharCount = count;
    response->outOperation.ack = ack;
    response->packetSeqNum = seqNums.incOutboundSeqNum();

    auto handle = std::get<sol::Manager&>(singletonPool).dataBuffer.read();
    std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload));
    expectedCharCount = readSize;

    enableRetryTimer(true);
    enableAccumulateTimer(false);

    sendPayload(payloadCache);
}

int Context::sendOutboundPayload()
{
    if (payloadCache.size() != 0)
    {
        enableAccumulateTimer(true);
        return -1;
    }

    auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.size();
    auto readSize = std::min(bufferSize, MAX_PAYLOAD_SIZE);

    payloadCache.resize(sizeof(Payload) + readSize);
    auto response = reinterpret_cast<Payload*>(payloadCache.data());
    response->packetAckSeqNum = 0;
    response->acceptedCharCount = 0;
    response->outOperation.ack = false;
    response->packetSeqNum = seqNums.incOutboundSeqNum();

    auto handle = std::get<sol::Manager&>(singletonPool).dataBuffer.read();
    std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload));
    expectedCharCount = readSize;

    enableRetryTimer(true);
    enableAccumulateTimer(false);

    sendPayload(payloadCache);

    return 0;
}

void Context::resendPayload(bool clear)
{
    sendPayload(payloadCache);

    if (clear)
    {
        payloadCache.clear();
        expectedCharCount = 0;
        std::get<sol::Manager&>(singletonPool)
            .dataBuffer.erase(expectedCharCount);
    }
}

void Context::sendPayload(const std::vector<uint8_t>& out) const
{
    message::Handler msgHandler(session->channelPtr, sessionID);

    msgHandler.sendSOLPayload(out);
}

void Context::charAccTimerHandler()
{
    auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.size();

    try
    {
        if (bufferSize > 0)
        {
            int rc = sendOutboundPayload();
            if (rc == 0)
            {
                return;
            }
        }
        enableAccumulateTimer(true);
    }
    catch (std::exception& e)
    {
        log<level::ERR>(e.what());
    }
}

void Context::retryTimerHandler()
{
    try
    {
        if (retryCounter)
        {
            --retryCounter;
            enableRetryTimer(true);
            resendPayload(sol::Context::noClear);
        }
        else
        {
            retryCounter = maxRetryCount;
            resendPayload(sol::Context::clear);
            enableRetryTimer(false);
            enableAccumulateTimer(true);
        }
    }
    catch (std::exception& e)
    {
        log<level::ERR>(e.what());
    }
}
} // namespace sol
