#include "file_io_type_cert.hpp"

#include "common/utils.hpp"

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

#include <phosphor-logging/lg2.hpp>

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
