// clang-format off
/********************************************************************************
*                       HON HAI Precision IND.Co., LTD.                         *
*            Personal Computer & Enterprise Product Business Group              *
*                      Enterprise Product Business Gro:qup                      *
*                                                                               *
*     Copyright (c) 2010 by FOXCONN/CESBG/CABG/SRD. All rights reserved.        *
*     All data and information contained in this document is confidential       *
*     and proprietary information of FOXCONN/CESBG/CABG/SRD and all rights      *
*     are reserved. By accepting this material the recipient agrees that        *
*     the information contained therein is held in confidence and in trust      *
*     and will not be used, copied, reproduced in whole or in part, nor its     *
*     contents revealed in any manner to others without the express written     *
*     permission of FOXCONN/CESBG/CABG/SRD.                                     *
*                                                                               *
********************************************************************************/
// clang-format on

#include <bioscommands.hpp>
#include <boost/endian/arithmetic.hpp>
#include <file_handling.hpp>
#include <ipmid/api.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/message/types.hpp>

struct bios_boot_count
{
    uint32_t header;
    uint32_t count;
};

namespace ipmi
{
static void registerBIOSFunctions() __attribute__((constructor));
ipmi::RspType<uint32_t>
    FiiBIOSBootCount([[maybe_unused]] boost::asio::yield_context yield,
                     std::vector<uint8_t> reqParams)
{
    int boot_count_operation;
    bios_boot_count boot;
    if (reqParams.empty())
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            " Fii bios cmd : command format error.");
        return ipmi::responseReqDataLenInvalid();
    }

    boot_count_operation = reqParams[0];

    if ((boot_count_operation == BOOT_COUNT_SET &&
         reqParams.size() != SET_BYTE_LENGTH) ||
        (boot_count_operation != BOOT_COUNT_SET &&
         reqParams.size() != OPERATION_BYTE_LENGTH))
    {
        return ipmi::responseReqDataLenInvalid();
    }

    if (boot_count_operation > BOOT_COUNT_SET)
    {
        return ipmi::responseInvalidCommand();
    }

    int fd = sysopen(EEPROM_PATH);
    readBin(fd, EEPROM_OFFSET, &boot, sizeof(boot));

    if (boot.header != BOOT_COUNT_HEADER)
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "Boot count header is corrupted or missing. Initializing.");
        boot.header = BOOT_COUNT_HEADER;
        boot.count = INITIAL_VALUE;
        writeBin(fd, EEPROM_OFFSET, &boot, sizeof(boot));
    }

    switch (boot_count_operation)
    {
        case BOOT_COUNT_READ:
            break;
        case BOOT_COUNT_INCREMENT:
            boot.count = boot.count + 1;
            break;
        case BOOT_COUNT_CLEAR:
            boot.count = INITIAL_VALUE;
            break;
        case BOOT_COUNT_SET:
            memcpy(&boot.count, &reqParams[1], sizeof(boot.count));
            break;
    }

    if (boot_count_operation != BOOT_COUNT_READ)
    {
        writeBin(fd, EEPROM_OFFSET + 4, &boot.count, sizeof(boot.count));
    }
    sysclose(fd);
    return ipmi::responseSuccess(boot.count);
}

void registerBIOSFunctions()
{
    std::fprintf(
        stderr,
        "Registering OEM:[0x34], Cmd:[%#04X] for Fii BIOS OEM Commands\n",
        FII_CMD_BIOS_BOOT_COUNT);
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnOemThree,
                          FII_CMD_BIOS_BOOT_COUNT, ipmi::Privilege::User,
                          FiiBIOSBootCount);
}
} // namespace ipmi
