#include "bios_table.hpp"

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

#include <phosphor-logging/lg2.hpp>

#include <fstream>

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& e)
    {
        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)
{
    auto sizeWithoutPad = table.size();
    auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
    table.resize(table.size() + padAndChecksumSize);

    pldm_bios_table_append_pad_checksum(table.data(), table.size(),
                                        sizeWithoutPad);
}

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)
    {
        lg2::error("Failed to encode BIOS table string entry: {LIBPLDM_ERROR}",
                   "LIBPLDM_ERROR", 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);
    pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
                                              entryLength, info);
    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)
    {
        lg2::error(
            "Failed to decode BIOS table string definition length: {LIBPLDM_ERROR}",
            "LIBPLDM_ERROR", 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)
    {
        lg2::error(
            "Failed to decode the number of possible values for BIOS table enum entry: {LIBPLDM_ERROR}",
            "LIBPLDM_ERROR", 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);
    pldm_bios_table_attr_value_entry_encode_string(
        table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
        str.c_str());
    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);
    pldm_bios_table_attr_value_entry_encode_integer(
        table.data() + tableSize, entryLength, attrHandle, attrType, value);
    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);
    pldm_bios_table_attr_value_entry_encode_enum(
        table.data() + tableSize, entryLength, attrHandle, attrType,
        handleIndices.size(), handleIndices.data());
    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
