#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);
    int rc = pldm_bios_table_attr_entry_integer_encode_check(
        table.data() + tableSize, entryLength, info);
    if (rc != PLDM_SUCCESS)
    {
        lg2::error(
            "Failed to encode BIOS attribute table integer entry: {LIBPLDM_ERROR}",
            "LIBPLDM_ERROR", 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)
    {
        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);
    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)
    {
        lg2::error(
            "Failed to encode BIOS attribute table string entry: {LIBPLDM_ERROR}",
            "LIBPLDM_ERROR", 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);
    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);
    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)
    {
        lg2::error(
            "Failed to encode BIOS attribute table enum entry: {LIBPLDM_ERROR}",
            "LIBPLDM_ERROR", 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
