#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;

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

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

    virtual void TearDown()
    {
        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[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:
    void command(const std::string& cmd)
    {
        auto val = std::system(cmd.c_str());
        if (val)
        {
            std::cout << "COMMAND Error: " << val << std::endl;
        }
    }
    virtual void SetUp()
    {
        // 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 + " 2048");

        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);
    }
    virtual void TearDown()
    {
        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:
    std::string readFile(fs::path path)
    {
        std::ifstream f(path, std::ios::in);
        const auto sz = fs::file_size(path);
        std::string result(sz, '\0');
        f.read(result.data(), sz);

        return result;
    }

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

    virtual void SetUp()
    {
        // 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);
    }

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

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

TEST_F(FileTest, TestMergeFiles)
{
    std::string retFile = tmpDir + "/retFile";
    for (auto file : srcFiles)
    {
        command("cat " + file + " >> " + retFile);
    }

    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);
}
