#include "pdr_file.hpp"

#include <libpldm/entity.h>

#include <phosphor-logging/lg2.hpp>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{
namespace pdr_file
{

using Json = nlohmann::json;

void generateFileDescriptorPDR(
    const Json& json, std::map<uint16_t, FileInfo>& fileIdentifierToFileInfo,
    std::map<uint32_t, FileInfo>& recordHandleToFileInfo,
    pdr_utils::RepoInterface& repo)
{
    static const std::vector<Json> emptyList{};
    auto entries = json.value("entries", emptyList);
    for (const auto& e : entries)
    {
        auto entityTypeIt = e.find("EntityType");
        if (entityTypeIt == e.end() || !entityTypeIt->is_number())
        {
            error("EntityType is missing or it is not a number.");
            continue;
        }

        uint16_t entityType = static_cast<uint16_t>(*entityTypeIt);
        if ((entityType != PLDM_ENTITY_DEVICE_FILE) &&
            (entityType != PLDM_ENTITY_DEVICE_FILE_DIRECTORY))
        {
            error(
                "Invalid EntityType '{ENTITY_TYPE}' for file descriptor PDR. Expected 9 or 10.",
                "ENTITY_TYPE", entityType);
            continue;
        }

        auto pathIt = e.find("Path");
        if (pathIt == e.end() || !pathIt->is_string())
        {
            error("'Path' is missing or it is not a string.");
            continue;
        }

        uint16_t container_id = e.value("container", 0);

        auto files = e.value("Files", emptyList);
        for (const auto& file : files)
        {
            auto fileIdIt = file.find("FileIdentifier");
            if (fileIdIt == file.end() || !fileIdIt->is_number())
            {
                error("FileIdentifier is missing or it is not a number.");
                continue;
            }

            auto fileNameIt = file.find("FileName");
            if (fileNameIt == file.end() || !fileNameIt->is_string())
            {
                error("FileName is missing or it is not a string.");
                continue;
            }

            auto fileSizeIt = file.find("FileSize");
            if (fileSizeIt == file.end() || !fileSizeIt->is_number())
            {
                error("FileSize is missing or it is not a string.");
                continue;
            }

            const std::string& fileName = fileNameIt.value();
            int fileNameLengthWithNull = fileName.length() + 1;

            // Calculate the total length of the PDR including the common PDR
            // header size. For now this skips the
            // OemFileClassificationNameLength and OemFileClassificationName
            // since they are not included.
            size_t pdrSize = PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH +
                             fileNameLengthWithNull;
            pldm_platform_file_descriptor_pdr pdr{};

            // This will be assigned automatically by PDR repository.
            pdr.hdr.record_handle = 0;
            pdr.hdr.version = 1;
            pdr.hdr.type = PLDM_FILE_DESCRIPTOR_PDR;
            pdr.hdr.record_change_num = 0;
            pdr.hdr.length = pdrSize - sizeof(pldm_pdr_hdr);

            pdr.terminus_handle = TERMINUS_HANDLE;
            pdr.file_identifier = *fileIdIt;
            pdr.container.entity_type = entityType;
            pdr.container.entity_instance_num = file.value("InstanceNumber", 0);
            pdr.container.entity_container_id = container_id;
            pdr.superior_directory_file_identifier =
                file.value("SuperiorDirectoryFileIdentifier", 0);
            pdr.file_classification = file.value("FileClassification", 0);
            pdr.oem_file_classification = 0;
            pdr.file_capabilities.value = file.value("FileCapabilities", 0);
            pdr.file_maximum_size = fileSizeIt.value();
            pdr.file_maximum_file_descriptor_count =
                file.value("MaxFileDescriptors", 0);
            pdr.file_name.ptr =
                reinterpret_cast<const uint8_t*>(fileName.c_str());
            pdr.file_name.length = fileNameLengthWithNull;
            pdr.oem_file_classification_name.ptr = nullptr;
            pdr.oem_file_classification_name.length = 0;

            std::vector<uint8_t> entry{};
            entry.resize(pdrSize);

            size_t pdrSizeCopy = pdrSize;
            int ret = encode_pldm_platform_file_descriptor_pdr(
                &pdr, entry.data(), &pdrSizeCopy);
            if (ret != 0)
            {
                error("Failed to encode file descriptor PDR for '{FILE_NAME}'",
                      "FILE_NAME", fileName);
                continue;
            }

            FileInfo fileInfo{};

            // Try opening the file here. If the open fail, we will not save the
            // PDR. If we do open the file later on, PDR information and the
            // actual file might not be in sync.
            fileInfo.filePath = pathIt->get<std::string>() + "/" + fileName;
            FILE* fp = fopen(fileInfo.filePath.c_str(), "rb");
            if (fp == nullptr)
            {
                error("Failed to open file '{FILE_PATH}'", "FILE_PATH",
                      fileInfo.filePath);
                continue;
            }

            // This file pointer will be kept open through out the lifetime of
            // the program
            // TODO: If the file changes during runtime, we need to load it
            // again. At that time we will close this and open a file pointer to
            // the new file.
            fileInfo.fp = fp;
            fileInfo.fileIdentifier = *fileIdIt;
            fileInfo.fileSize = fileSizeIt.value();

            pdr_utils::PdrEntry pdrEntry{};
            pdrEntry.data = entry.data();
            pdrEntry.size = pdrSize;
            pdr_utils::RecordHandle recordHandle;

            try
            {
                recordHandle = repo.addRecord(pdrEntry);
            }
            catch (const std::runtime_error& e)
            {
                error("Error adding record for file '{FILE_PATH}'", "FILE_PATH",
                      fileInfo.filePath);
                continue;
            }

            fileInfo.recordHandle = static_cast<uint32_t>(recordHandle);

            fileIdentifierToFileInfo.try_emplace(*fileIdIt, fileInfo);
            recordHandleToFileInfo.try_emplace(
                static_cast<uint32_t>(recordHandle), fileInfo);
        }
    }
}

} // namespace pdr_file
} // namespace responder
} // namespace pldm
