#include "config.h"

#include "oemcommands.hpp"

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>

#include <array>
#include <cstdint>
#include <fstream>
#include <string>
#include <vector>

constexpr char biosPasswordFilePath[] =
    "/var/lib/bios-settings-manager/seedData";
constexpr int biosPasswordIter = 1000;
constexpr uint8_t biosPasswordSaltSize = 32;
constexpr uint8_t biosPasswordMaxHashSize = 64;
constexpr uint8_t biosPasswordTypeNoChange = 0x00;
constexpr uint8_t biosPasswordSelectorAdmin = 0x01;
constexpr uint8_t biosPasswordTypeNoPassowrd = 0x01;
constexpr uint8_t biosPasswordTypePbkdf2Sha256 = 0x02;
constexpr uint8_t biosPasswordTypePbkdf2Sha384 = 0x03;

void registerBiosConfigCommands() __attribute__((constructor));

namespace ipmi
{
ipmi::RspType<> ipmiSetBiosPassword(
    uint8_t id, uint8_t type, std::array<uint8_t, biosPasswordSaltSize> salt,
    std::array<uint8_t, biosPasswordMaxHashSize> hash)
{
    nlohmann::json json;

    if (id != biosPasswordSelectorAdmin)
    {
        return ipmi::responseInvalidFieldRequest();
    }
    // key names for json object
    constexpr char keyHashAlgo[] = "HashAlgo";
    constexpr char keySeed[] = "Seed";
    constexpr char keyAdminPwdHash[] = "AdminPwdHash";
    constexpr char keyIsAdminPwdChanged[] = "IsAdminPwdChanged";
    constexpr char keyIsUserPwdChanged[] = "IsUserPwdChanged";
    constexpr char keyUserPwdHash[] = "UserPwdHash";

    switch (type)
    {
        case biosPasswordTypeNoPassowrd:
            json[keyHashAlgo] = "SHA256";
            RAND_bytes(salt.data(), salt.size());
            // password is only Null-terminated character
            PKCS5_PBKDF2_HMAC("", 1, salt.data(), salt.size(), biosPasswordIter,
                              EVP_sha256(), SHA256_DIGEST_LENGTH, hash.data());
            json[keySeed] = salt;
            json[keyAdminPwdHash] = hash;
            break;
        case biosPasswordTypePbkdf2Sha256:
            json[keyHashAlgo] = "SHA256";
            json[keySeed] = salt;
            json[keyAdminPwdHash] = hash;
            break;
        case biosPasswordTypePbkdf2Sha384:
            json[keyHashAlgo] = "SHA384";
            json[keySeed] = salt;
            json[keyAdminPwdHash] = hash;
            break;
        default:
            return ipmi::responseInvalidFieldRequest();
    }

    json[keyIsAdminPwdChanged] = false;
    json[keyIsUserPwdChanged] = false;

    // initializing with 0 as user password hash field
    // is not used presently
    constexpr std::array<uint8_t, biosPasswordMaxHashSize> userPwdHash = {0};
    json[keyUserPwdHash] = userPwdHash;

    try
    {
        std::ofstream ofs(biosPasswordFilePath, std::ios::out);
        const auto& writeData = json.dump();
        ofs << writeData;
        ofs.close();
    }
    catch (std::exception& e)
    {
        lg2::error("Failed to save BIOS Password information: {ERROR}", "ERROR",
                   e.what());
        return ipmi::responseUnspecifiedError();
    }
    return ipmi::responseSuccess();
}

ipmi::RspType<uint8_t,                                     // action
              std::array<uint8_t, biosPasswordSaltSize>,   // salt
              std::array<uint8_t, biosPasswordMaxHashSize> // hash
              >
    ipmiGetBiosPassword(uint8_t id)
{
    uint8_t action = biosPasswordTypeNoChange;
    std::array<uint8_t, biosPasswordSaltSize> salt = {0};
    std::array<uint8_t, biosPasswordMaxHashSize> hash = {0};

    if (id != biosPasswordSelectorAdmin)
    {
        return ipmi::responseParmOutOfRange();
    }

    std::ifstream ifs(biosPasswordFilePath);
    if (!ifs.is_open())
    {
        // return No change if no file
        return ipmi::responseSuccess(action, salt, hash);
    }

    // key names for json object
    constexpr char keyIsAdminPwdChanged[] = "IsAdminPwdChanged";
    constexpr char keyHashAlgo[] = "HashAlgo";
    constexpr char keySeed[] = "Seed";
    constexpr char keyAdminPwdHash[] = "AdminPwdHash";

    nlohmann::json json = nlohmann::json::parse(ifs, nullptr, false);
    if (json.is_discarded() || !json.contains(keyIsAdminPwdChanged) ||
        !json.contains(keyHashAlgo) || !json.contains(keySeed) ||
        !json.contains(keyAdminPwdHash))
    {
        return ipmi::responseResponseError();
    }
    bool IsAdminPwdChanged = json[keyIsAdminPwdChanged];
    if (IsAdminPwdChanged == false)
    {
        return ipmi::responseSuccess(action, salt, hash);
    }

    salt = json[keySeed];
    hash = json[keyAdminPwdHash];

    std::string HashAlgo = json[keyHashAlgo];
    auto digest = EVP_sha256();
    int keylen = SHA256_DIGEST_LENGTH;

    if (HashAlgo == "SHA256")
    {
        action = biosPasswordTypePbkdf2Sha256;
    }
    else if (HashAlgo == "SHA384")
    {
        action = biosPasswordTypePbkdf2Sha384;
        digest = EVP_sha384();
        keylen = SHA384_DIGEST_LENGTH;
    }

    std::array<uint8_t, biosPasswordMaxHashSize> nullHash = {0};
    PKCS5_PBKDF2_HMAC("", 1, salt.data(), salt.size(), biosPasswordIter, digest,
                      keylen, nullHash.data());
    if (hash == nullHash)
    {
        action = biosPasswordTypeNoPassowrd;
        salt.fill(0x00);
        hash.fill(0x00);
    }

    return ipmi::responseSuccess(action, salt, hash);
}
} // namespace ipmi

void registerBiosConfigCommands()
{
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::groupNvidia,
                          ipmi::bios_password::cmdSetBiosPassword,
                          ipmi::Privilege::Admin, ipmi::ipmiSetBiosPassword);
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::groupNvidia,
                          ipmi::bios_password::cmdGetBiosPassword,
                          ipmi::Privilege::Admin, ipmi::ipmiGetBiosPassword);
}
