#include "config.h"

#include "image_verify.hpp"
#include "utils.hpp"
#include "version.hpp"

#include <openssl/evp.h>
#include <stdlib.h>

#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <gtest/gtest.h>

using namespace phosphor::software::manager;
using namespace phosphor::software::image;

namespace fs = std::filesystem;

class VersionTest : public testing::Test
{
  protected:
    void SetUp() override
    {
        char versionDir[] = "./versionXXXXXX";
        _directory = mkdtemp(versionDir);

        if (_directory.empty())
        {
            throw std::bad_alloc();
        }
    }

    void TearDown() override
    {
        fs::remove_all(_directory);
    }

    std::string _directory;
};

/** @brief Make sure we correctly get the version and purpose from getValue()*/
TEST_F(VersionTest, TestGetValue)
{
    auto manifestFilePath = _directory + "/" + "MANIFEST";
    auto version = "test-version";
    auto purpose = "BMC";

    std::ofstream file;
    file.open(manifestFilePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    file << "version=" << version << "\n";
    file << "purpose=" << purpose << "\n";
    file.close();

    EXPECT_EQ(Version::getValue(manifestFilePath, "version"), version);
    EXPECT_EQ(Version::getValue(manifestFilePath, "purpose"), purpose);
}

TEST_F(VersionTest, TestGetRepeatedValue)
{
    auto manifestFilePath = _directory + "/" + "MANIFEST";
    const std::vector<std::string> names = {"foo.bar", "baz.bim"};

    std::ofstream file;
    file.open(manifestFilePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    for (const auto& name : names)
    {
        file << "CompatibleName=" << name << "\n";
    }
    file.close();

    EXPECT_EQ(Version::getRepeatedValues(manifestFilePath, "CompatibleName"),
              names);
}

TEST_F(VersionTest, TestGetValueWithCRLF)
{
    auto manifestFilePath = _directory + "/" + "MANIFEST";
    auto version = "test-version";
    auto purpose = "BMC";

    std::ofstream file;
    file.open(manifestFilePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    file << "version=" << version << "\r\n";
    file << "purpose=" << purpose << "\r\n";
    file.close();

    EXPECT_EQ(Version::getValue(manifestFilePath, "version"), version);
    EXPECT_EQ(Version::getValue(manifestFilePath, "purpose"), purpose);
}

TEST_F(VersionTest, TestGetVersionWithQuotes)
{
    auto releasePath = _directory + "/" + "os-release";
    auto version = "1.2.3-test-version";

    std::ofstream file;
    file.open(releasePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    file << "VERSION_ID=\"" << version << "\"\n";
    file.close();

    EXPECT_EQ(Version::getBMCVersion(releasePath), version);
}

TEST_F(VersionTest, TestGetVersionWithoutQuotes)
{
    auto releasePath = _directory + "/" + "os-release";
    auto version = "9.88.1-test-version";

    std::ofstream file;
    file.open(releasePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    file << "VERSION_ID=" << version << "\n";
    file.close();

    EXPECT_EQ(Version::getBMCVersion(releasePath), version);
}

/** @brief Make sure we correctly get the Id from getId()*/
TEST_F(VersionTest, TestGetId)
{
    auto version = "test-id";
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int digest_count = 0;

    EVP_MD_CTX_Ptr ctx(EVP_MD_CTX_new(), &::EVP_MD_CTX_free);

    EVP_DigestInit(ctx.get(), EVP_sha512());
    EVP_DigestUpdate(ctx.get(), version, strlen(version));
    EVP_DigestFinal(ctx.get(), digest, &digest_count);

    char mdString[EVP_MAX_MD_SIZE * 2 + 1];
    for (decltype(digest_count) i = 0; i < digest_count; i++)
    {
        snprintf(&mdString[static_cast<size_t>(i) * 2], 3, "%02x",
                 (unsigned int)digest[i]);
    }
    std::string hexId = std::string(mdString);
    hexId = hexId.substr(0, 8);
    EXPECT_EQ(Version::getId(version), hexId);
}

TEST_F(VersionTest, TestGetExtendedVersion)
{
    auto releasePath = _directory + "/" + "os-release";
    auto ExtendedVersion = "9.88.1-test-ExtendedVersion";

    std::ofstream file;
    file.open(releasePath, std::ofstream::out);
    ASSERT_TRUE(file.is_open());

    file << "EXTENDED_VERSION=" << ExtendedVersion << "\n";
    file.close();

    EXPECT_EQ(Version::getBMCExtendedVersion(releasePath), ExtendedVersion);
}

class SignatureTest : public testing::Test
{
  public:
    static constexpr auto opensslCmd = "openssl dgst -sha256 -sign ";
    static constexpr auto testPath = "/tmp/_testSig";

  protected:
    static void command(const std::string& cmd)
    {
        auto val = std::system(cmd.c_str());
        if (val)
        {
            std::cout << "COMMAND Error: " << val << std::endl;
        }
    }
    void SetUp() override
    {
        // Create test base directory.
        fs::create_directories(testPath);

        // Create unique temporary path for images
        std::string tmpDir(testPath);
        tmpDir += "/extractXXXXXX";
        std::string imageDir = mkdtemp(const_cast<char*>(tmpDir.c_str()));

        // Create unique temporary configuration path
        std::string tmpConfDir(testPath);
        tmpConfDir += "/confXXXXXX";
        std::string confDir = mkdtemp(const_cast<char*>(tmpConfDir.c_str()));

        extractPath = imageDir;
        extractPath /= "images";

        signedConfPath = confDir;
        signedConfPath /= "conf";

        signedConfOpenBMCPath = confDir;
        signedConfOpenBMCPath /= "conf";
        signedConfOpenBMCPath /= "OpenBMC";

        std::cout << "SETUP " << std::endl;

        command("mkdir " + extractPath.string());
        command("mkdir " + signedConfPath.string());
        command("mkdir " + signedConfOpenBMCPath.string());

        std::string hashFile = signedConfOpenBMCPath.string() + "/hashfunc";
        command("echo \"HashType=RSA-SHA256\" > " + hashFile);

        std::string manifestFile = extractPath.string() + "/" + "MANIFEST";
        command(
            "echo \"purpose=xyz.openbmc_project.Software.Version.VersionPurpose.BMC\" > " +
            manifestFile);
        command("echo \"HashType=RSA-SHA256\" >> " + manifestFile);
        command("echo \"KeyType=OpenBMC\" >> " + manifestFile);

        std::string kernelFile = extractPath.string() + "/" + "image-kernel";
        command("echo \"image-kernel file \" > " + kernelFile);

        std::string rofsFile = extractPath.string() + "/" + "image-rofs";
        command("echo \"image-rofs file \" > " + rofsFile);

        std::string rwfsFile = extractPath.string() + "/" + "image-rwfs";
        command("echo \"image-rwfs file \" > " + rwfsFile);

        std::string ubootFile = extractPath.string() + "/" + "image-u-boot";
        command("echo \"image-u-boot file \" > " + ubootFile);

        std::string pkeyFile = extractPath.string() + "/" + "private.pem";
        command("openssl genrsa  -out " + pkeyFile + " 4096");

        std::string pubkeyFile = extractPath.string() + "/" + "publickey";
        command("openssl rsa -in " + pkeyFile + " -outform PEM " +
                "-pubout -out " + pubkeyFile);

        command("cp " + pubkeyFile + " " + signedConfOpenBMCPath.string());
        command(opensslCmd + pkeyFile + " -out " + kernelFile + ".sig " +
                kernelFile);

        command(opensslCmd + pkeyFile + " -out " + manifestFile + ".sig " +
                manifestFile);
        command(opensslCmd + pkeyFile + " -out " + rofsFile + ".sig " +
                rofsFile);
        command(opensslCmd + pkeyFile + " -out " + rwfsFile + ".sig " +
                rwfsFile);
        command(opensslCmd + pkeyFile + " -out " + ubootFile + ".sig " +
                ubootFile);
        command(opensslCmd + pkeyFile + " -out " + pubkeyFile + ".sig " +
                pubkeyFile);

#ifdef WANT_SIGNATURE_VERIFY
        std::string fullFile = extractPath.string() + "/" + "image-full";
        command("cat " + kernelFile + ".sig " + rofsFile + ".sig " + rwfsFile +
                ".sig " + ubootFile + ".sig " + manifestFile + ".sig " +
                pubkeyFile + ".sig > " + fullFile);
        command(opensslCmd + pkeyFile + " -out " + fullFile + ".sig " +
                fullFile);
#endif

        signature = std::make_unique<Signature>(extractPath, signedConfPath);
    }
    void TearDown() override
    {
        command("rm -rf " + std::string(testPath));
    }

    std::unique_ptr<Signature> signature;
    fs::path extractPath;
    fs::path signedConfPath;
    fs::path signedConfOpenBMCPath;
};

/** @brief Test for success scenario*/
TEST_F(SignatureTest, TestSignatureVerify)
{
    EXPECT_TRUE(signature->verify());
}

/** @brief Test failure scenario with corrupted signature file*/
TEST_F(SignatureTest, TestCorruptSignatureFile)
{
    // corrupt the image-kernel.sig file and ensure that verification fails
    std::string kernelFile = extractPath.string() + "/" + "image-kernel";
    command("echo \"dummy data\" > " + kernelFile + ".sig ");
    EXPECT_FALSE(signature->verify());
}

/** @brief Test failure scenario with no public key in the image*/
TEST_F(SignatureTest, TestNoPublicKeyInImage)
{
    // Remove publickey file from the image and ensure that verify fails
    std::string pubkeyFile = extractPath.string() + "/" + "publickey";
    command("rm " + pubkeyFile);
    EXPECT_FALSE(signature->verify());
}

/** @brief Test failure scenario with invalid hash function value*/
TEST_F(SignatureTest, TestInvalidHashValue)
{
    // Change the hashfunc value and ensure that verification fails
    std::string hashFile = signedConfOpenBMCPath.string() + "/hashfunc";
    command("echo \"HashType=md5\" > " + hashFile);
    EXPECT_FALSE(signature->verify());
}

/** @brief Test for failure scenario with no config file in system*/
TEST_F(SignatureTest, TestNoConfigFileInSystem)
{
    // Remove the conf folder in the system and ensure that verify fails
    command("rm -rf " + signedConfOpenBMCPath.string());
    EXPECT_FALSE(signature->verify());
}

#ifdef WANT_SIGNATURE_VERIFY
/** @brief Test for failure scenario without full verification */
TEST_F(SignatureTest, TestNoFullSignature)
{
    // Remove the full signature and ensure that verify fails
    std::string fullFile = extractPath.string() + "/" + "image-full.sig";
    command("rm " + fullFile);
    EXPECT_FALSE(signature->verify());
}

/** @brief Test for failure scenario without full verification */
TEST_F(SignatureTest, TestNoFullSignatureForBIOS)
{
    // Remove the full signature
    std::string fullFile = extractPath.string() + "/" + "image-full.sig";
    command("rm " + fullFile);

    // Change the purpose to BIOS
    std::string manifestFile = extractPath.string() + "/" + "MANIFEST";
    std::string pkeyFile = extractPath.string() + "/" + "private.pem";
    command("sed -i s/VersionPurpose.BMC/VersionPurpose.BIOS/ " + manifestFile);
    command(opensslCmd + pkeyFile + " -out " + manifestFile + ".sig " +
            manifestFile);

    // Re-create signature object and make sure verify succeed.
    signature = std::make_unique<Signature>(extractPath, signedConfPath);
    EXPECT_TRUE(signature->verify());
}
#endif

class FileTest : public testing::Test
{
  protected:
    static std::string readFile(const fs::path& path)
    {
        std::ifstream f(path, std::ios::in);
        if (!f.is_open())
        {
            throw "Failed to open file";
        }

        auto sz = static_cast<std::streamsize>(fs::file_size(path));
        std::string result(static_cast<size_t>(sz), '\0');
        f.read(result.data(), sz);

        return result;
    }

    static void command(const std::string& cmd)
    {
        auto val = std::system(cmd.c_str());
        if (val)
        {
            std::cout << "COMMAND Error: " << val << std::endl;
        }
    }

    void SetUp() override
    {
        // Create test base directory.
        tmpDir = fs::temp_directory_path() / "testFileXXXXXX";
        if (!mkdtemp(tmpDir.data()))
        {
            throw "Failed to create tmp dir";
        }

        std::string file1 = tmpDir + "/file1";
        std::string file2 = tmpDir + "/file2";
        command("echo \"File Test1\n\n\" > " + file1);
        command("echo \"FileTe st2\n\nte st2\" > " + file2);

        srcFiles.push_back(file1);
        srcFiles.push_back(file2);
    }

    void TearDown() override
    {
        fs::remove_all(tmpDir);
    }

    std::vector<std::string> srcFiles;
    std::string tmpDir;
};

TEST_F(FileTest, TestMergeFiles)
{
    std::string retFile = tmpDir + "/retFile";
    std::stringstream ss;
    ss << "cat";
    for (const auto& file : srcFiles)
    {
        ss << " " << file;
    }
    ss << " >> " << retFile;
    std::string catCommand = ss.str();
    command(catCommand);

    std::string dstFile = tmpDir + "/dstFile";
    utils::mergeFiles(srcFiles, dstFile);

    ASSERT_NE(fs::file_size(retFile), static_cast<uintmax_t>(-1));
    ASSERT_NE(fs::file_size(dstFile), static_cast<uintmax_t>(-1));
    ASSERT_EQ(fs::file_size(retFile), fs::file_size(dstFile));

    std::string ssRetFile = readFile(fs::path(retFile));
    std::string ssDstFile = readFile(fs::path(dstFile));
    ASSERT_EQ(ssRetFile, ssDstFile);
}

TEST(ExecTest, TestConstructArgv)
{
    auto name = "/bin/ls";
    auto arg1 = "-a";
    auto arg2 = "-l";
    auto arg3 = "-t";
    auto arg4 = "-rS";
    auto argV = utils::internal::constructArgv(name, arg1, arg2, arg3, arg4);
    char** charArray = argV.data();
    EXPECT_EQ(argV.size(), 6);
    EXPECT_EQ(charArray[0], name);
    EXPECT_EQ(charArray[1], arg1);
    EXPECT_EQ(charArray[2], arg2);
    EXPECT_EQ(charArray[3], arg3);
    EXPECT_EQ(charArray[4], arg4);
    EXPECT_EQ(charArray[5], nullptr);

    name = "/usr/bin/du";
    argV = utils::internal::constructArgv(name);
    charArray = argV.data();
    EXPECT_EQ(argV.size(), 2);
    EXPECT_EQ(charArray[0], name);
    EXPECT_EQ(charArray[1], nullptr);

    name = "/usr/bin/hexdump";
    arg1 = "-C";
    arg2 = "/path/to/filename";
    argV = utils::internal::constructArgv(name, arg1, arg2);
    charArray = argV.data();
    EXPECT_EQ(argV.size(), 4);
    EXPECT_EQ(charArray[0], name);
    EXPECT_EQ(charArray[1], arg1);
    EXPECT_EQ(charArray[2], arg2);
    EXPECT_EQ(charArray[3], nullptr);
}
