#pragma once
#include "openssl_alloc.hpp"
#include "version.hpp"

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <sys/mman.h>
#include <unistd.h>

#include <filesystem>
#include <set>
#include <string>
#include <vector>

namespace phosphor
{
namespace software
{
namespace image
{

namespace fs = std::filesystem;
using Key_t = std::string;
using Hash_t = std::string;
using PublicKeyPath = fs::path;
using HashFilePath = fs::path;
using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
using AvailableKeyTypes = std::set<Key_t>;
using VersionPurpose =
    sdbusplus::server::xyz::openbmc_project::software::Version::VersionPurpose;

// RAII support for openSSL functions.
using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using EVP_MD_CTX_Ptr =
    std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;

/** @struct CustomFd
 *
 *  RAII wrapper for file descriptor.
 */
struct CustomFd
{
  public:
    CustomFd() = delete;
    CustomFd(const CustomFd&) = delete;
    CustomFd& operator=(const CustomFd&) = delete;
    CustomFd(CustomFd&&) = default;
    CustomFd& operator=(CustomFd&&) = default;
    /** @brief Saves File descriptor and uses it to do file operation
     *
     *  @param[in] fd - File descriptor
     */
    explicit CustomFd(int fd) : fd(fd) {}

    ~CustomFd()
    {
        if (fd >= 0)
        {
            close(fd);
        }
    }

    int operator()() const
    {
        return fd;
    }

  private:
    /** @brief File descriptor */
    int fd = -1;
};

/** @struct CustomMap
 *
 *  RAII wrapper for mmap.
 */
struct CustomMap
{
  private:
    /** @brief starting address of the map   */
    void* addr;

    /** @brief length of the mapping   */
    size_t length;

  public:
    CustomMap() = delete;
    CustomMap(const CustomMap&) = delete;
    CustomMap& operator=(const CustomMap&) = delete;
    CustomMap(CustomMap&&) = default;
    CustomMap& operator=(CustomMap&&) = default;

    /** @brief Saves starting address of the map and
     *         and length of the file.
     *  @param[in]  addr - Starting address of the map
     *  @param[in]  length - length of the map
     */
    CustomMap(void* addr, size_t length) : addr(addr), length(length) {}

    ~CustomMap()
    {
        munmap(addr, length);
    }

    void* operator()() const
    {
        return addr;
    }
};

/** @class Signature
 *  @brief Contains signature verification functions.
 *  @details The software image class that contains the signature
 *           verification functions for signed image.
 */
class Signature
{
  public:
    Signature() = delete;
    Signature(const Signature&) = delete;
    Signature& operator=(const Signature&) = delete;
    Signature(Signature&&) = default;
    Signature& operator=(Signature&&) = default;
    ~Signature() = default;

    /**
     * @brief Constructs Signature.
     * @param[in]  imageDirPath - image path
     * @param[in]  signedConfPath - Path of public key
     *                              hash function files
     */
    Signature(const fs::path& imageDirPath, const fs::path& signedConfPath);

    /**
     * @brief Image signature verification function.
     *        Verify the Manifest and public key file signature using the
     *        public keys available in the system first. After successful
     *        validation, continue the whole image files signature
     *        validation using the image specific public key and the
     *        hash function.
     *
     *        @return true if signature verification was successful,
     *                     false if not
     */
    bool verify();

  private:
    /**
     * @brief Function used for system level file signature validation
     *        of image specific publickey file and manifest file
     *        using the available public keys and hash functions
     *        in the system.
     *        Refer code-update documentation for more details.
     */
    bool systemLevelVerify();

    /**
     *  @brief Return all key types stored in the BMC based on the
     *         public key and hashfunc files stored in the BMC.
     *
     *  @return list
     */
    AvailableKeyTypes getAvailableKeyTypesFromSystem() const;

    /**
     *  @brief Return public key and hash function file names for the
     *  corresponding key type
     *
     *  @param[in]  key - key type
     *  @return Pair of hash and public key file names
     */
    inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const;

    /**
     * @brief Verify the file signature using public key and hash function
     *
     * @param[in]  - Image file path
     * @param[in]  - Signature file path
     * @param[in]  - Public key
     * @param[in]  - Hash function name
     * @return true if signature verification was successful, false if not
     */
    static bool verifyFile(const fs::path& file, const fs::path& signature,
                           const fs::path& publicKey,
                           const std::string& hashFunc);

    /**
     * @brief Create RSA object from the public key
     * @param[in]  - publickey
     * @param[out] - RSA Object.
     */
    static inline EVP_PKEY_Ptr createPublicRSA(const fs::path& publicKey);

    /**
     * @brief Memory map the  file
     * @param[in]  - file path
     * @param[in]  - file size
     * @param[out] - Custom Mmap address
     */
    static CustomMap mapFile(const fs::path& path, size_t size);

    /**
     * @brief Verify the full file signature using public key and hash function
     *
     * @return true if signature verification was successful, false if not
     */
    bool verifyFullImage();

    /** @brief Directory where software images are placed*/
    fs::path imageDirPath;

    /** @brief Path of public key and hash function files */
    fs::path signedConfPath;

    /** @brief key type defined in manifest file */
    Key_t keyType;

    /** @brief Hash type defined in manifest file */
    Hash_t hashType;

    /** @brief The image purpose */
    VersionPurpose purpose;

    /** @brief Check and Verify the required image files
     *
     * @param[in] filePath - BMC tarball file path
     * @param[in] publicKeyPath - publicKey file Path
     * @param[in] imageList - Image filenames included in the BMC tarball
     * @param[out] fileFound - Indicate if the file to verify is found or not
     *
     * @return true if all image files are found in BMC tarball and
     * Verify Success false if one of image files is missing
     */
    bool checkAndVerifyImage(const std::string& filePath,
                             const std::string& publicKeyPath,
                             const std::vector<std::string>& imageList,
                             bool& fileFound);
};

} // namespace image
} // namespace software
} // namespace phosphor
