#pragma once

#include "watch.hpp"

#include <openssl/ossl_typ.h>
#include <openssl/x509.h>

#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Certs/Certificate/server.hpp>
#include <xyz/openbmc_project/Certs/Replace/server.hpp>
#include <xyz/openbmc_project/Object/Delete/server.hpp>

#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>

namespace phosphor::certs
{

// Certificate types
enum class CertificateType
{
    authority,
    server,
    client,
    unsupported,
};

inline constexpr const char* certificateTypeToString(CertificateType type)
{
    switch (type)
    {
        case CertificateType::authority:
            return "authority";
        case CertificateType::server:
            return "server";
        case CertificateType::client:
            return "client";
        default:
            return "unsupported";
    }
}

inline constexpr CertificateType stringToCertificateType(std::string_view type)
{
    if (type == "authority")
    {
        return CertificateType::authority;
    }
    if (type == "server")
    {
        return CertificateType::server;
    }
    if (type == "client")
    {
        return CertificateType::client;
    }
    return CertificateType::unsupported;
}

namespace internal
{
using CertificateInterface = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Certs::server::Certificate,
    sdbusplus::xyz::openbmc_project::Certs::server::Replace,
    sdbusplus::xyz::openbmc_project::Object::server::Delete>;
using InstallFunc = std::function<void(const std::string&)>;
using AppendPrivKeyFunc = std::function<void(const std::string&)>;
using X509Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
} // namespace internal

class Manager; // Forward declaration for Certificate Manager.

/** @class Certificate
 *  @brief OpenBMC Certificate entry implementation.
 *  @details A concrete implementation for the
 *  xyz.openbmc_project.Certs.Certificate DBus API
 *  xyz.openbmc_project.Certs.Install DBus API
 */
class Certificate : public internal::CertificateInterface
{
  public:
    Certificate() = delete;
    Certificate(const Certificate&) = delete;
    Certificate& operator=(const Certificate&) = delete;
    Certificate(Certificate&&) = delete;
    Certificate& operator=(Certificate&&) = delete;
    virtual ~Certificate();

    /** @brief Constructor for the Certificate Object
     *  @param[in] bus - Bus to attach to.
     *  @param[in] objPath - Object path to attach to
     *  @param[in] type - Type of the certificate
     *  @param[in] installPath - Path of the certificate to install
     *  @param[in] uploadPath - Path of the certificate file to upload
     *  @param[in] watchPtr - watch on self signed certificate
     *  @param[in] parent - the manager that owns the certificate
     *  @param[in] restore - the certificate is created in the restore path
     */
    Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
                CertificateType type, const std::string& installPath,
                const std::string& uploadPath, Watch* watch, Manager& parent,
                bool restore);

    /** @brief Constructor for the Certificate Object; a variant for authorities
     * list install
     *  @param[in] bus - Bus to attach to.
     *  @param[in] objPath - Object path to attach to
     *  @param[in] type - Type of the certificate
     *  @param[in] installPath - Path of the certificate to install
     *  @param[in] x509Store - an initialized X509 store used for certificate
     * validation; Certificate object doesn't own it
     *  @param[in] pem - Content of the certificate file to upload; it shall be
     * a single PEM encoded x509 certificate
     *  @param[in] watchPtr - watch on self signed certificate
     *  @param[in] parent - Pointer to the manager which owns the constructed
     * Certificate object
     *  @param[in] restore - the certificate is created in the restore path
     */
    Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
                const CertificateType& type, const std::string& installPath,
                X509_STORE& x509Store, const std::string& pem, Watch* watchPtr,
                Manager& parent, bool restore);

    /** @brief Validate and Replace/Install the certificate file
     *  Install/Replace the existing certificate file with another
     *  (possibly CA signed) Certificate file.
     *  @param[in] filePath - Certificate file path.
     *  @param[in] restore - the certificate is created in the restore path
     */
    void install(const std::string& filePath, bool restore);

    /** @brief Validate and Replace/Install the certificate file
     *  Install/Replace the existing certificate file with another
     *  (possibly CA signed) Certificate file.
     *  @param[in] x509Store - an initialized X509 store used for certificate
     * validation; Certificate object doesn't own it
     *  @param[in] pem - a string buffer which stores a PEM encoded certificate.
     *  @param[in] restore - the certificate is created in the restore path
     */
    void install(X509_STORE& x509Store, const std::string& pem, bool restore);

    /** @brief Validate certificate and replace the existing certificate
     *  @param[in] filePath - Certificate file path.
     */
    void replace(const std::string filePath) override;

    /** @brief Populate certificate properties by parsing certificate file
     */
    void populateProperties();

    /**
     * @brief Obtain certificate ID.
     *
     * @return Certificate ID.
     */
    std::string getCertId() const;

    /**
     * @brief Check if provided certificate is the same as the current one.
     *
     * @param[in] certPath - File path for certificate to check.
     *
     * @return Checking result. Return true if certificates are the same,
     *         false if not.
     */
    bool isSame(const std::string& certPath);

    /**
     * @brief Update certificate storage.
     */
    void storageUpdate();

    /**
     * @brief Delete the certificate
     */
    void delete_() override;

    /**
     * @brief Generate file name which is unique in the provided directory.
     *
     * @param[in] directoryPath - Directory path.
     *
     * @return File path.
     */
    static std::string generateUniqueFilePath(const std::string& directoryPath);

    /**
     * @brief Copies the certificate from sourceFilePath to installFilePath
     *
     * @param[in] sourceFilePath - Path to the source file.
     * @param[in] certFilePath - Path to the destination file.
     *
     * @return void
     */
    static void copyCertificate(const std::string& certSrcFilePath,
                                const std::string& certFilePath);

    /**
     * @brief Returns the associated dbus object path.
     */
    std::string getObjectPath();

    /**
     * @brief Returns the associated cert file path.
     */
    std::string getCertFilePath();

    /** @brief: Set the data member |certFilePath| to |path|
     */
    void setCertFilePath(const std::string& path);

    /** @brief: Set the data member |certInstallPath| to |path|
     */
    void setCertInstallPath(const std::string& path);

  private:
    /**
     * @brief Populate certificate properties by parsing given certificate
     * object
     *
     * @param[in] cert The given certificate object
     *
     * @return void
     */
    void populateProperties(X509& cert);

    /** @brief Check and append private key to the certificate file
     *         If private key is not present in the certificate file append the
     *         certificate file with private key existing in the system.
     *  @param[in] filePath - Certificate and key full file path.
     *  @return void.
     */
    void checkAndAppendPrivateKey(const std::string& filePath);

    /** @brief Public/Private key compare function.
     *         Comparing private key against certificate public key
     *         from input .pem file.
     *  @param[in] filePath - Certificate and key full file path.
     *  @return Return true if Key compare is successful,
     *          false if not
     */
    bool compareKeys(const std::string& filePath);

    /**
     * @brief Generate authority certificate file path corresponding with
     * OpenSSL requirements.
     *
     * Prepare authority certificate file path for provided certificate.
     * OpenSSL puts some restrictions on the certificate file name pattern.
     * Certificate full file name needs to consists of basic file name which
     * is certificate subject name hash and file name extension which is an
     * integer. More over, certificates files names extensions must be
     * consecutive integer numbers in case many certificates with the same
     * subject name.
     * https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html
     * https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html
     *
     * @param[in] certSrcFilePath - Certificate source file path.
     * @param[in] certDstDirPath - Certificate destination directory path.
     *
     * @return Authority certificate file path.
     */
    std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath,
                                             const std::string& certDstDirPath);

    /**
     * @brief Generate authority certificate file path based on provided
     * certificate source file path.
     *
     * @param[in] certSrcFilePath - Certificate source file path.
     *
     * @return Authority certificate file path.
     */
    std::string generateAuthCertFilePath(const std::string& certSrcFilePath);

    /**
     * @brief Generate certificate file path based on provided certificate
     * source file path.
     *
     * @param[in] certSrcFilePath - Certificate source file path.
     *
     * @return Certificate file path.
     */
    std::string generateCertFilePath(const std::string& certSrcFilePath);

    /** @brief Type specific function pointer map */
    std::unordered_map<CertificateType, internal::InstallFunc> typeFuncMap;

    /** @brief object path */
    std::string objectPath;

    /** @brief Type of the certificate */
    CertificateType certType;

    /** @brief Stores certificate ID */
    std::string certId;

    /** @brief Stores certificate file path */
    std::string certFilePath;

    /** @brief Certificate file installation path */
    std::string certInstallPath;

    /** @brief Type specific function pointer map for appending private key */
    std::unordered_map<CertificateType, internal::AppendPrivKeyFunc>
        appendKeyMap;

    /** @brief Certificate file create/update watch
     * Note that Certificate object doesn't own the pointer
     */
    Watch* certWatch;

    /** @brief Reference to Certificate Manager */
    Manager& manager;
};

} // namespace phosphor::certs
