#include "bios.hpp"

#include "common/utils.hpp"

#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/Time/EpochTime/common.hpp>
#include <xyz/openbmc_project/Time/Synchronization/common.hpp>

#include <chrono>
#include <ctime>
#include <string>
#include <vector>

PHOSPHOR_LOG2_USING;

using EpochTime = sdbusplus::common::xyz::openbmc_project::time::EpochTime;
using TimeSynchronization =
    sdbusplus::common::xyz::openbmc_project::time::Synchronization;

using namespace pldm::utils;

namespace pldm
{
namespace responder
{
namespace utils
{
void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
                    uint8_t& hours, uint8_t& day, uint8_t& month,
                    uint16_t& year)
{
    auto t = time_t(timeSec);
    auto time = localtime(&t);

    seconds = pldm::utils::decimalToBcd(time->tm_sec);
    minutes = pldm::utils::decimalToBcd(time->tm_min);
    hours = pldm::utils::decimalToBcd(time->tm_hour);
    day = pldm::utils::decimalToBcd(time->tm_mday);
    month = pldm::utils::decimalToBcd(
        time->tm_mon + 1);     // The number of months in the range
                               // 0 to 11.PLDM expects range 1 to 12
    year = pldm::utils::decimalToBcd(
        time->tm_year + 1900); // The number of years since 1900
}

std::time_t timeToEpoch(uint8_t seconds, uint8_t minutes, uint8_t hours,
                        uint8_t day, uint8_t month, uint16_t year)
{
    struct std::tm stm;

    stm.tm_year = year - 1900;
    stm.tm_mon = month - 1;
    stm.tm_mday = day;
    stm.tm_hour = hours;
    stm.tm_min = minutes;
    stm.tm_sec = seconds;
    stm.tm_isdst = -1;

    // It will get the time in seconds since
    // Epoch, 1970.1.1 00:00:00 +0000,UTC.
    return timegm(&stm);
}

} // namespace utils

namespace bios
{
using EpochTimeUS = uint64_t;

DBusHandler dbusHandler;

Handler::Handler(
    int fd, uint8_t eid, pldm::InstanceIdDb* instanceIdDb,
    pldm::requester::Handler<pldm::requester::Request>* handler,
    pldm::responder::platform_config::Handler* platformConfigHandler,
    pldm::responder::bios::Callback requestPLDMServiceName) :
    biosConfig(BIOS_JSONS_DIR, BIOS_TABLES_DIR, &dbusHandler, fd, eid,
               instanceIdDb, handler, platformConfigHandler,
               requestPLDMServiceName)
{
    handlers.emplace(
        PLDM_SET_DATE_TIME,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->setDateTime(request, payloadLength);
        });
    handlers.emplace(
        PLDM_GET_DATE_TIME,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->getDateTime(request, payloadLength);
        });
    handlers.emplace(
        PLDM_GET_BIOS_TABLE,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->getBIOSTable(request, payloadLength);
        });
    handlers.emplace(
        PLDM_SET_BIOS_TABLE,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->setBIOSTable(request, payloadLength);
        });
    handlers.emplace(
        PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->getBIOSAttributeCurrentValueByHandle(request,
                                                              payloadLength);
        });
    handlers.emplace(
        PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE,
        [this](pldm_tid_t, const pldm_msg* request, size_t payloadLength) {
            return this->setBIOSAttributeCurrentValue(request, payloadLength);
        });
}

Response Handler::getDateTime(const pldm_msg* request, size_t /*payloadLength*/)
{
    uint8_t seconds = 0;
    uint8_t minutes = 0;
    uint8_t hours = 0;
    uint8_t day = 0;
    uint8_t month = 0;
    uint16_t year = 0;

    constexpr auto bmcTimePath = "/xyz/openbmc_project/time/bmc";
    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;
    EpochTimeUS timeUsec = 0;

    try
    {
        timeUsec = pldm::utils::DBusHandler().getDbusProperty<EpochTimeUS>(
            bmcTimePath, EpochTime::property_names::elapsed,
            EpochTime::interface);
    }
    catch (const sdbusplus::exception_t& e)
    {
        error(
            "Error getting time from Elapsed property at path '{PATH}' on interface '{INTERFACE}': {ERROR}",
            "PATH", bmcTimePath, "INTERFACE", EpochTime::interface, "ERROR", e);
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
    }

    uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
                           std::chrono::microseconds(timeUsec))
                           .count();

    pldm::responder::utils::epochToBCDTime(timeSec, seconds, minutes, hours,
                                           day, month, year);

    auto rc = encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS,
                                        seconds, minutes, hours, day, month,
                                        year, responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::setDateTime(const pldm_msg* request, size_t payloadLength)
{
    uint8_t seconds = 0;
    uint8_t minutes = 0;
    uint8_t hours = 0;
    uint8_t day = 0;
    uint8_t month = 0;
    uint16_t year = 0;
    std::time_t timeSec = 0;

    constexpr auto timeSyncPath = "/xyz/openbmc_project/time/sync_method";

    // The time is correct on BMC when in NTP mode, so we do not want to
    // try and set the time again and cause potential time drifts.
    try
    {
        auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
            timeSyncPath, TimeSynchronization::property_names::time_sync_method,
            TimeSynchronization::interface);
        const auto& mode = std::get<std::string>(propVal);

        if (mode == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
        {
            return ccOnlyResponse(request, PLDM_SUCCESS);
        }
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to get the time sync property from path {TIME_SYNC_PATH}, interface '{SYNC_INTERFACE}' and property '{SYNC_PROPERTY}', error - '{ERROR}'",
            "TIME_SYNC_PATH", timeSyncPath, "SYNC_INTERFACE",
            TimeSynchronization::interface, "SYNC_PROPERTY",
            TimeSynchronization::property_names::time_sync_method, "ERROR", e);
    }

    constexpr auto setTimePath = "/xyz/openbmc_project/time/bmc";

    auto rc = decode_set_date_time_req(request, payloadLength, &seconds,
                                       &minutes, &hours, &day, &month, &year);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }
    timeSec = pldm::responder::utils::timeToEpoch(seconds, minutes, hours, day,
                                                  month, year);
    uint64_t timeUsec = std::chrono::duration_cast<std::chrono::microseconds>(
                            std::chrono::seconds(timeSec))
                            .count();
    PropertyValue value{timeUsec};
    try
    {
        DBusMapping dbusMapping{setTimePath, EpochTime::interface,
                                EpochTime::property_names::elapsed, "uint64_t"};
        pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to set time at {SET_TIME_PATH}, interface '{TIME_INTERFACE}' and error - {ERROR}",
            "SET_TIME_PATH", setTimePath, "TIME_INTERFACE",
            EpochTime::interface, "ERROR", e);
        return ccOnlyResponse(request, PLDM_ERROR);
    }

    return ccOnlyResponse(request, PLDM_SUCCESS);
}

Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
{
    uint32_t transferHandle{};
    uint8_t transferOpFlag{};
    uint8_t tableType{};

    auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
                                        &transferOpFlag, &tableType);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    auto table =
        biosConfig.getBIOSTable(static_cast<pldm_bios_table_types>(tableType));
    if (!table)
    {
        return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
    }

    Response response(sizeof(pldm_msg_hdr) +
                      PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + table->size());
    auto responsePtr = new (response.data()) pldm_msg;

    rc = encode_get_bios_table_resp(
        request->hdr.instance_id, PLDM_SUCCESS, 0 /* nxtTransferHandle */,
        PLDM_START_AND_END, table->data(), response.size(), responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::setBIOSTable(const pldm_msg* request, size_t payloadLength)
{
    uint32_t transferHandle{};
    uint8_t transferOpFlag{};
    uint8_t tableType{};
    struct variable_field field;

    auto rc = decode_set_bios_table_req(request, payloadLength, &transferHandle,
                                        &transferOpFlag, &tableType, &field);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    Table table(field.ptr, field.ptr + field.length);
    rc = biosConfig.setBIOSTable(tableType, table);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    Response response(sizeof(pldm_msg_hdr) + PLDM_SET_BIOS_TABLE_RESP_BYTES);
    auto responsePtr = new (response.data()) pldm_msg;

    rc = encode_set_bios_table_resp(request->hdr.instance_id, PLDM_SUCCESS,
                                    0 /* nxtTransferHandle */, responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::getBIOSAttributeCurrentValueByHandle(const pldm_msg* request,
                                                       size_t payloadLength)
{
    uint32_t transferHandle = 0;
    uint8_t transferOpFlag = 0;
    uint16_t attributeHandle = 0;

    auto rc = decode_get_bios_attribute_current_value_by_handle_req(
        request, payloadLength, &transferHandle, &transferOpFlag,
        &attributeHandle);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    auto table = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
    if (!table)
    {
        return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
    }

    auto entry = pldm_bios_table_attr_value_find_by_handle(
        table->data(), table->size(), attributeHandle);
    if (entry == nullptr)
    {
        return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
    }

    auto entryLength = pldm_bios_table_attr_value_entry_length(entry);
    Response response(sizeof(pldm_msg_hdr) +
                          PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
                          entryLength,
                      0);
    auto responsePtr = new (response.data()) pldm_msg;
    rc = encode_get_bios_current_value_by_handle_resp(
        request->hdr.instance_id, PLDM_SUCCESS, 0, PLDM_START_AND_END,
        reinterpret_cast<const uint8_t*>(entry), entryLength, responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::setBIOSAttributeCurrentValue(const pldm_msg* request,
                                               size_t payloadLength)
{
    uint32_t transferHandle = 0;
    uint8_t transferOpFlag = 0;
    variable_field attributeField;

    auto rc = decode_set_bios_attribute_current_value_req(
        request, payloadLength, &transferHandle, &transferOpFlag,
        &attributeField);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    rc = biosConfig.setAttrValue(attributeField.ptr, attributeField.length,
                                 false);

    Response response(
        sizeof(pldm_msg_hdr) + PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;

    encode_set_bios_attribute_current_value_resp(request->hdr.instance_id, rc,
                                                 0, responsePtr);

    return response;
}

} // namespace bios
} // namespace responder
} // namespace pldm
