#include "bios_table.hpp"

#include <libpldm/base.h>
#include <libpldm/bios_table.h>
#include <libpldm/utils.h>

#include <phosphor-logging/lg2.hpp>

#include <fstream>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{
namespace bios
{
BIOSTable::BIOSTable(const char* filePath) : filePath(filePath) {}

bool BIOSTable::isEmpty() const noexcept
{
    bool empty = false;
    try
    {
        empty = fs::is_empty(filePath);
    }
    catch (const fs::filesystem_error&)
    {
        return true;
    }
    return empty;
}

void BIOSTable::store(const Table& table)
{
    std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
    stream.write(reinterpret_cast<const char*>(table.data()), table.size());
}

void BIOSTable::load(Response& response) const
{
    auto currSize = response.size();
    auto fileSize = fs::file_size(filePath);
    response.resize(currSize + fileSize);
    std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
    stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
}

BIOSStringTable::BIOSStringTable(const Table& stringTable) :
    stringTable(stringTable)
{}

BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
{
    biosTable.load(stringTable);
}

std::string BIOSStringTable::findString(uint16_t handle) const
{
    auto stringEntry = pldm_bios_table_string_find_by_handle(
        stringTable.data(), stringTable.size(), handle);
    if (stringEntry == nullptr)
    {
        throw std::invalid_argument("Invalid String Handle");
    }
    return table::string::decodeString(stringEntry);
}

uint16_t BIOSStringTable::findHandle(const std::string& name) const
{
    auto stringEntry = pldm_bios_table_string_find_by_string(
        stringTable.data(), stringTable.size(), name.c_str());
    if (stringEntry == nullptr)
    {
        throw std::invalid_argument("Invalid String Name");
    }

    return table::string::decodeHandle(stringEntry);
}

namespace table
{
void appendPadAndChecksum(Table& table)
{
    size_t payloadSize = table.size();
    table.resize(payloadSize + pldm_bios_table_pad_checksum_size(payloadSize));
    // No validation of return value as preconditions are satisfied
    pldm_bios_table_append_pad_checksum_check(table.data(), table.size(),
                                              &payloadSize);
}

namespace string
{
uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
{
    return pldm_bios_table_string_entry_decode_handle(entry);
}

std::string decodeString(const pldm_bios_string_table_entry* entry)
{
    auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
    std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
    // Preconditions are upheld therefore no error check necessary
    pldm_bios_table_string_entry_decode_string_check(entry, buffer.data(),
                                                     buffer.size());
    return std::string(buffer.data(), buffer.data() + strLength);
}
const pldm_bios_string_table_entry* constructEntry(Table& table,
                                                   const std::string& str)
{
    auto tableSize = table.size();
    auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
    table.resize(tableSize + entryLength);
    // Preconditions are upheld therefore no error check necessary
    pldm_bios_table_string_entry_encode_check(
        table.data() + tableSize, entryLength, str.c_str(), str.length());
    return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
                                                           tableSize);
}

} // namespace string

namespace attribute
{
TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
{
    auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
    auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
    auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
    return {attrHandle, attrType, stringHandle};
}

const pldm_bios_attr_table_entry* findByHandle(const Table& table,
                                               uint16_t handle)
{
    return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
                                               handle);
}

const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
                                                     uint16_t handle)
{
    return pldm_bios_table_attr_find_by_string_handle(table.data(),
                                                      table.size(), handle);
}

const pldm_bios_attr_table_entry*
    constructStringEntry(Table& table,
                         pldm_bios_table_attr_entry_string_info* info)
{
    auto entryLength =
        pldm_bios_table_attr_entry_string_encode_length(info->def_length);

    auto tableSize = table.size();
    table.resize(tableSize + entryLength, 0);
    int rc = pldm_bios_table_attr_entry_string_encode_check(
        table.data() + tableSize, entryLength, info);
    if (rc != PLDM_SUCCESS)
    {
        error("Failed to encode BIOS table string entry, response code '{RC}'",
              "RC", rc);
        throw std::runtime_error("Failed to encode BIOS table string entry");
    }
    return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
                                                         tableSize);
}

const pldm_bios_attr_table_entry*
    constructIntegerEntry(Table& table,
                          pldm_bios_table_attr_entry_integer_info* info)
{
    auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
    auto tableSize = table.size();
    table.resize(tableSize + entryLength, 0);
    int rc = pldm_bios_table_attr_entry_integer_encode_check(
        table.data() + tableSize, entryLength, info);
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to encode BIOS attribute table integer entry");
    }
    return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
                                                         tableSize);
}

StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
{
    auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
    auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
    auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
    uint16_t defLength;
    int rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
        entry, &defLength);
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to decode BIOS table string definition length, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to decode BIOS table string definitionlength");
    }

    std::vector<char> buffer(defLength + 1);
    pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
                                                        buffer.size());
    return {strType, minLength, maxLength, defLength,
            std::string(buffer.data(), buffer.data() + defLength)};
}

IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
{
    uint64_t lower, upper, def;
    uint32_t scalar;

    pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
                                              &def);
    return {lower, upper, scalar, def};
}

const pldm_bios_attr_table_entry*
    constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
{
    auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
        info->pv_num, info->def_num);

    auto tableSize = table.size();
    table.resize(tableSize + entryLength, 0);
    // Preconditions are upheld therefore no error check necessary
    pldm_bios_table_attr_entry_enum_encode_check(table.data() + tableSize,
                                                 entryLength, info);

    return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
                                                         tableSize);
}

EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
{
    uint8_t pvNum;
    int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNum);
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to decode the number of possible values for BIOS table enum entry, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to decode the number of possible values for BIOS table enum entry");
    }
    std::vector<uint16_t> pvHdls(pvNum, 0);
    // Preconditions are upheld therefore no error check necessary
    pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(entry, pvHdls.data(),
                                                         pvNum);
    // Preconditions are upheld therefore no error check necessary
    uint8_t defNum;
    pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNum);
    std::vector<uint8_t> defIndices(defNum, 0);
    pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
                                                       defIndices.size());
    return {pvHdls, defIndices};
}

} // namespace attribute

namespace attribute_value
{
TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
{
    auto handle =
        pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
    auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
    return {handle, type};
}

std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
{
    variable_field currentString{};
    pldm_bios_table_attr_value_entry_string_decode_string(entry,
                                                          &currentString);
    return std::string(currentString.ptr,
                       currentString.ptr + currentString.length);
}

uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
{
    return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
}

std::vector<uint8_t>
    decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
{
    auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
    std::vector<uint8_t> currHdls(number, 0);
    pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
                                                         currHdls.size());
    return currHdls;
}

const pldm_bios_attr_val_table_entry*
    constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
                         const std::string& str)
{
    auto strLen = str.size();
    auto entryLength =
        pldm_bios_table_attr_value_entry_encode_string_length(strLen);
    auto tableSize = table.size();
    table.resize(tableSize + entryLength);
    int rc = pldm_bios_table_attr_value_entry_encode_string_check(
        table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
        str.c_str());
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to encode BIOS attribute table string entry, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to encode BIOS attribute table string entry");
    }
    return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
                                                             tableSize);
}

const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
                                                            uint16_t attrHandle,
                                                            uint8_t attrType,
                                                            uint64_t value)
{
    auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();

    auto tableSize = table.size();
    table.resize(tableSize + entryLength);
    int rc = pldm_bios_table_attr_value_entry_encode_integer_check(
        table.data() + tableSize, entryLength, attrHandle, attrType, value);
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to encode BIOS attribute table integery entry");
    }
    return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
                                                             tableSize);
}

const pldm_bios_attr_val_table_entry*
    constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
                       const std::vector<uint8_t>& handleIndices)
{
    auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
        handleIndices.size());
    auto tableSize = table.size();
    table.resize(tableSize + entryLength);
    int rc = pldm_bios_table_attr_value_entry_encode_enum_check(
        table.data() + tableSize, entryLength, attrHandle, attrType,
        handleIndices.size(), handleIndices.data());
    if (rc != PLDM_SUCCESS)
    {
        error(
            "Failed to encode BIOS attribute table enum entry, response code '{RC}'",
            "RC", rc);
        throw std::runtime_error(
            "Failed to encode BIOS attribute table enum entry");
    }
    return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
                                                             tableSize);
}

std::optional<Table> updateTable(const Table& table, const void* entry,
                                 size_t size)
{
    // Replace the old attribute with the new attribute, the size of table will
    // change:
    //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
    //                      sizeof(oldAttribute) + pad(4-byte alignment, max =
    //                      3)
    // For simplicity, we use
    //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
    size_t destBufferLength = table.size() + size + 3;
    Table destTable(destBufferLength);

    auto rc = pldm_bios_table_attr_value_copy_and_update(
        table.data(), table.size(), destTable.data(), &destBufferLength, entry,
        size);
    if (rc != PLDM_SUCCESS)
    {
        return std::nullopt;
    }
    destTable.resize(destBufferLength);

    return destTable;
}

} // namespace attribute_value

} // namespace table

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