#include "file_io_type_cert.hpp"

#include "common/utils.hpp"

#include <libpldm/base.h>
#include <libpldm/file_io.h>
#include <stdint.h>

#include <phosphor-logging/lg2.hpp>

#include <iostream>

PHOSPHOR_LOG2_USING;

namespace pldm
{
using namespace utils;

namespace responder
{
constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";

CertMap CertHandler::certMap;

int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
                                 uint64_t address,
                                 oem_platform::Handler* /*oemPlatformHandler*/)
{
    auto it = certMap.find(certType);
    if (it == certMap.end())
    {
        error(
            "CertHandler::writeFromMemory:file for type {CERT_TYPE} doesn't exist",
            "CERT_TYPE", certType);
        return PLDM_ERROR;
    }

    auto fd = std::get<0>(it->second);
    auto& remSize = std::get<1>(it->second);
    auto rc = transferFileData(fd, false, offset, length, address);
    if (rc == PLDM_SUCCESS)
    {
        remSize -= length;
        if (!remSize)
        {
            close(fd);
            certMap.erase(it);
        }
    }
    return rc;
}

int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
                                uint64_t address,
                                oem_platform::Handler* /*oemPlatformHandler*/)
{
    std::string filePath = certFilePath;
    filePath += "CSR_" + std::to_string(fileHandle);
    if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
    fs::remove(filePath);
    if (rc)
    {
        return PLDM_ERROR;
    }
    return PLDM_SUCCESS;
}

int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
                      oem_platform::Handler* /*oemPlatformHandler*/)
{
    info(
        "CertHandler::read:Read file response for Sign CSR, file handle: {FILE_HANDLE}",
        "FILE_HANDLE", fileHandle);
    std::string filePath = certFilePath;
    filePath += "CSR_" + std::to_string(fileHandle);
    if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    auto rc = readFile(filePath.c_str(), offset, length, response);
    fs::remove(filePath);
    if (rc)
    {
        return PLDM_ERROR;
    }
    return PLDM_SUCCESS;
}

int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
                       oem_platform::Handler* /*oemPlatformHandler*/)
{
    auto it = certMap.find(certType);
    if (it == certMap.end())
    {
        error("CertHandler::write:file for type {CERT_TYPE} doesn't exist",
              "CERT_TYPE", certType);
        return PLDM_ERROR;
    }

    auto fd = std::get<0>(it->second);
    int rc = lseek(fd, offset, SEEK_SET);
    if (rc == -1)
    {
        error("CertHandler::write:lseek failed, ERROR={ERR}, OFFSET={OFFSET}",
              "ERR", errno, "OFFSET", offset);
        return PLDM_ERROR;
    }
    rc = ::write(fd, buffer, length);
    if (rc == -1)
    {
        error(
            "CertHandler::write:file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
            "ERR", errno, "LEN", length, "OFFSET", offset);
        return PLDM_ERROR;
    }
    length = rc;
    auto& remSize = std::get<1>(it->second);
    remSize -= length;
    if (!remSize)
    {
        close(fd);
        certMap.erase(it);
    }

    if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
    {
        constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
        constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";

        std::string filePath = certFilePath;
        filePath += "ClientCert_" + std::to_string(fileHandle);

        std::ifstream inFile;
        inFile.open(filePath);
        std::stringstream strStream;
        strStream << inFile.rdbuf();
        std::string str = strStream.str();
        inFile.close();

        if (!str.empty())
        {
            PropertyValue value{str};

            DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
                                    certEntryIntf, "ClientCertificate",
                                    "string"};
            try
            {
                pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
            }
            catch (const std::exception& e)
            {
                error(
                    "CertHandler::write:failed to set Client certificate, ERROR={ERR_EXCEP}",
                    "ERR_EXCEP", e.what());
                return PLDM_ERROR;
            }
            PropertyValue valueStatus{
                "xyz.openbmc_project.Certs.Entry.State.Complete"};
            DBusMapping dbusMappingStatus{certObjPath +
                                              std::to_string(fileHandle),
                                          certEntryIntf, "Status", "string"};
            try
            {
                info(
                    "CertHandler::write:Client cert write, status: complete. File handle: {FILE_HANDLE}",
                    "FILE_HANDLE", fileHandle);
                pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
                                                           valueStatus);
            }
            catch (const std::exception& e)
            {
                error(
                    "CertHandler::write:failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
                    "ERR_EXCEP", e.what());
                return PLDM_ERROR;
            }
            fs::remove(filePath);
        }
        else
        {
            PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
            DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
                                    certEntryIntf, "Status", "string"};
            try
            {
                info(
                    "CertHandler::write:Client cert write, status: Bad CSR. File handle: {FILE_HANDLE}",
                    "FILE_HANDLE", fileHandle);
                pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
            }
            catch (const std::exception& e)
            {
                error(
                    "CertHandler::write:failed to set status property of certicate entry, {ERR_EXCEP}",
                    "ERR_EXCEP", e.what());
                return PLDM_ERROR;
            }
        }
    }
    return PLDM_SUCCESS;
}

int CertHandler::newFileAvailable(uint64_t length)
{
    fs::create_directories(certFilePath);
    fs::permissions(certFilePath,
                    fs::perms::others_read | fs::perms::owner_write);
    int fileFd = -1;
    int flags = O_WRONLY | O_CREAT | O_TRUNC;
    std::string filePath = certFilePath;

    if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
    {
        info(
            "CertHandler::newFileAvailable:new file available client cert file, file handle: {FILE_HANDLE}",
            "FILE_HANDLE", fileHandle);
        fileFd = open(
            (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
            flags, S_IRUSR | S_IWUSR);
    }
    else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
    {
        fileFd = open((filePath + "RootCert").c_str(), flags,
                      S_IRUSR | S_IWUSR);
    }
    if (fileFd == -1)
    {
        error(
            "CertHandler::newFileAvailable:failed to open file for type {CERT_TYPE} ERROR={ERR}",
            "CERT_TYPE", certType, "ERR", errno);
        return PLDM_ERROR;
    }
    certMap.emplace(certType, std::tuple(fileFd, length));
    return PLDM_SUCCESS;
}

int CertHandler::newFileAvailableWithMetaData(uint64_t length,
                                              uint32_t metaDataValue1,
                                              uint32_t /*metaDataValue2*/,
                                              uint32_t /*metaDataValue3*/,
                                              uint32_t /*metaDataValue4*/)
{
    fs::create_directories(certFilePath);
    fs::permissions(certFilePath,
                    fs::perms::others_read | fs::perms::owner_write);
    int fileFd = -1;
    int flags = O_WRONLY | O_CREAT | O_TRUNC;
    std::string filePath = certFilePath;

    if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
    {
        return PLDM_ERROR_INVALID_DATA;
    }
    if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
    {
        if (metaDataValue1 == PLDM_SUCCESS)
        {
            error(
                "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: {FILE_HANDLE}",
                "FILE_HANDLE", fileHandle);
            fileFd = open(
                (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
                flags, S_IRUSR | S_IWUSR);
        }
        else if (metaDataValue1 == PLDM_INVALID_CERT_DATA)
        {
            error(
                "newFileAvailableWithMetaData:client cert file Invalid data, file handle: {FILE_HANDLE}",
                "FILE_HANDLE", fileHandle);
            DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
                                    certEntryIntf, "Status", "string"};
            std::string status = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
            PropertyValue value{status};
            try
            {
                pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
            }
            catch (const std::exception& e)
            {
                error(
                    "newFileAvailableWithMetaData:Failed to set status property of certicate entry, ERROR= {ERR_EXCEP}",
                    "ERR_EXCEP", e.what());
                return PLDM_ERROR;
            }
        }
    }
    else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
    {
        fileFd = open((filePath + "RootCert").c_str(), flags,
                      S_IRUSR | S_IWUSR);
    }
    if (fileFd == -1)
    {
        error(
            "newFileAvailableWithMetaData:failed to open file for type {CERT_TYPE} ERROR={ERR}",
            "CERT_TYPE", certType, "ERR", errno);
        return PLDM_ERROR;
    }
    certMap.emplace(certType, std::tuple(fileFd, length));
    return PLDM_SUCCESS;
}

int CertHandler::fileAckWithMetaData(uint8_t fileStatus,
                                     uint32_t /*metaDataValue1*/,
                                     uint32_t /*metaDataValue2*/,
                                     uint32_t /*metaDataValue3*/,
                                     uint32_t /*metaDataValue4*/)
{
    if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
    {
        DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
                                certEntryIntf, "Status", "string"};
        PropertyValue value = "xyz.openbmc_project.Certs.Entry.State.Pending";
        if (fileStatus == PLDM_ERROR_INVALID_DATA)
        {
            value = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
        }
        else if (fileStatus == PLDM_ERROR_NOT_READY)
        {
            value = "xyz.openbmc_project.Certs.Entry.State.Pending";
        }
        try
        {
            pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
        }
        catch (const std::exception& e)
        {
            error(
                "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
                "ERR_EXCEP", e.what());
            return PLDM_ERROR;
        }
    }
    return PLDM_SUCCESS;
}

} // namespace responder
} // namespace pldm
