#pragma once

#include "certificate.hpp"
#include "csr.hpp"
#include "watch.hpp"

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

#include <cstdint>
#include <filesystem>
#include <memory>
#include <sdbusplus/server/object.hpp>
#include <sdeventplus/source/child.hpp>
#include <sdeventplus/source/event.hpp>
#include <string>
#include <vector>
#include <xyz/openbmc_project/Certs/CSR/Create/server.hpp>
#include <xyz/openbmc_project/Certs/Install/server.hpp>
#include <xyz/openbmc_project/Certs/InstallAll/server.hpp>
#include <xyz/openbmc_project/Certs/ReplaceAll/server.hpp>
#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>

namespace phosphor::certs
{

namespace internal
{
using ManagerInterface = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Certs::server::Install,
    sdbusplus::xyz::openbmc_project::Certs::CSR::server::Create,
    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll,
    sdbusplus::xyz::openbmc_project::Certs::server::InstallAll,
    sdbusplus::xyz::openbmc_project::Certs::server::ReplaceAll>;
}

class Manager : public internal::ManagerInterface
{
  public:
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor is not possible due to member
     *           reference
     *         - Move operations due to 'this' being registered as the
     *           'context' with sdbus.
     *     Allowed:
     *         - copy
     *         - Destructor.
     */
    Manager() = delete;
    Manager(const Manager&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager(Manager&&) = delete;
    Manager& operator=(Manager&&) = delete;
    virtual ~Manager() = default;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] event - sd event handler.
     *  @param[in] path - Path to attach at.
     *  @param[in] type - Type of the certificate.
     *  @param[in] unit - Unit consumed by this certificate.
     *  @param[in] installPath - Certificate installation path.
     */
    Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
            const char* path, CertificateType type, const std::string& unit,
            const std::string& installPath);

    /** @brief Implementation for Install
     *  Replace the existing certificate key file with another
     *  (possibly CA signed) Certificate key file.
     *
     *  @param[in] filePath - Certificate key file path.
     *
     *  @return Certificate object path.
     */
    std::string install(const std::string filePath) override;

    /** @brief Implementation for InstallAll
     *  Install the authority list and restart the associated services.
     *
     *  @param[in] path - Path of the file that contains a list of root
     * certificates.
     *
     *  @return D-Bus object path to created objects.
     */
    std::vector<sdbusplus::message::object_path>
        installAll(std::string path) override;

    /** @brief Implementation for ReplaceAll
     *  Replace the current authority lists and restart the associated services.
     *
     *  @param[in] path - Path of file that contains multiple root certificates.
     *
     *  @return D-Bus object path to created objects.
     */
    std::vector<sdbusplus::message::object_path>
        replaceAll(std::string filePath) override;

    /** @brief Implementation for DeleteAll
     *  Delete all objects in the collection.
     */
    void deleteAll() override;

    /** @brief Delete the certificate.
     */
    void deleteCertificate(const Certificate* const certificate);

    /** @brief Replace the certificate.
     */
    void replaceCertificate(Certificate* const certificate,
                            const std::string& filePath);

    /** @brief Generate Private key and CSR file
     *  Generates the Private key file and CSR file based on the input
     *  parameters. Validation of the parameters is callers responsibility.
     *  At present supports only RSA algorithm type
     *
     *  @param[in] alternativeNames - Additional hostnames of the component that
     *      is being secured.
     *  @param[in] challengePassword - The challenge password to be applied to
     *      the certificate for revocation requests.
     *  @param[in] city - The city or locality of the organization making the
     *      request. For Example Austin
     *  @param[in] commonName - The fully qualified domain name of the component
     *      that is being secured.
     *  @param[in] contactPerson - The name of the user making the request.
     *  @param[in] country - The country of the organization making the request.
     *  @param[in] email - The email address of the contact within the
     *      organization making the request.
     *  @param[in] givenName - The given name of the user making the request.
     *  @param[in] initials - The initials of the user making the request.
     *  @param[in] keyBitLength - The length of the key in bits, if needed based
     *      on the value of the KeyPairAlgorithm parameter.
     *  @param[in] keyCurveId - The curve ID to be used with the key, if needed
     *      based on the value of the KeyPairAlgorithm parameter.
     *  @param[in] keyPairAlgorithm - The type of key pair for use with signing
     *      algorithms. Valid built-in algorithm names for private key
     *      generation are: RSA, DSA, DH and EC.
     *  @param[in] keyUsage - Key usage extensions define the purpose of the
     *      public key contained in a certificate. Valid Key usage extensions
     *      and its usage description.
     *      - ClientAuthentication: The public key is used for TLS WWW client
     *      authentication.
     *      - CodeSigning: The public key is used for the signing of executable
     *          code
     *      - CRLSigning: The public key is used for verifying signatures on
     *          certificate revocation lists (CLRs).
     *      - DataEncipherment: The public key is used for directly enciphering
     *          raw user data without the use of an intermediate symmetric
     *          cipher.
     *      - DecipherOnly: The public key could be used for deciphering data
     *          while performing key agreement.
     *      - DigitalSignature: The public key is used for verifying digital
     *          signatures, other than signatures on certificatesand CRLs.
     *      - EmailProtection: The public key is used for email protection.
     *      - EncipherOnly: Thepublic key could be used for enciphering data
     *          while performing key agreement.
     *      - KeyCertSign: The public key is used for verifying signatures on
     *          public key certificates.
     *      - KeyEncipherment: The public key is used for enciphering private or
     *          secret keys.
     *      - NonRepudiation: The public key is used to verify digital
     *          signatures, other than signatures on certificates and CRLs, and
     *          used to provide a non-repudiation service that protects against
     *          the signing entity falsely denying some action.
     *      - OCSPSigning: The public key is used for signing OCSP responses.
     *      - ServerAuthentication: The public key is used for TLS WWW server
     *          authentication.
     *      - Timestamping: The public key is used for binding the hash of an
     *          object to a time.
     *  @param[in] organization - The legal name of the organization. This
     *      should not be abbreviated and should include suffixes such as Inc,
     *      Corp, or LLC.For example, IBM Corp.
     *  @param[in] organizationalUnit - The name of the unit or division of the
     *      organization making the request.
     *  @param[in] state - The state or province where the organization is
     *      located. This should not be abbreviated. For example, Texas.
     *  @param[in] surname - The surname of the user making the request.
     *  @param[in] unstructuredName - The unstructured name of the subject.
     *
     *  @return path[std::string] - The object path of the D-Bus object
     *      representing CSR string. Note: For new CSR request will overwrite
     * the existing CSR in the system.
     */
    std::string generateCSR(
        std::vector<std::string> alternativeNames,
        std::string challengePassword, std::string city, std::string commonName,
        std::string contactPerson, std::string country, std::string email,
        std::string givenName, std::string initials, int64_t keyBitLength,
        std::string keyCurveId, std::string keyPairAlgorithm,
        std::vector<std::string> keyUsage, std::string organization,
        std::string organizationalUnit, std::string state, std::string surname,
        std::string unstructuredName) override;

    /** @brief Get reference to certificates' collection
     *
     *  @return Reference to certificates' collection
     */
    std::vector<std::unique_ptr<Certificate>>& getCertificates();

    /** @brief Systemd unit reload or reset helper function
     *  Reload if the unit supports it and use a restart otherwise.
     *  @param[in] unit - service need to reload.
     */
    virtual void reloadOrReset(const std::string& unit);

  private:
    void generateCSRHelper(std::vector<std::string> alternativeNames,
                           std::string challengePassword, std::string city,
                           std::string commonName, std::string contactPerson,
                           std::string country, std::string email,
                           std::string givenName, std::string initials,
                           int64_t keyBitLength, std::string keyCurveId,
                           std::string keyPairAlgorithm,
                           std::vector<std::string> keyUsage,
                           std::string organization,
                           std::string organizationalUnit, std::string state,
                           std::string surname, std::string unstructuredName);

    /** @brief Generate RSA Key pair and get private key from key pair
     *  @param[in]  keyBitLength - KeyBit length.
     *  @return     Pointer to RSA private key
     */
    std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
        generateRSAKeyPair(const int64_t keyBitLength);

    /** @brief Generate EC Key pair and get private key from key pair
     *  @param[in]  p_KeyCurveId - Curve ID
     *  @return     Pointer to EC private key
     */
    std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
        generateECKeyPair(const std::string& p_KeyCurveId);

    /** @brief Write private key data to file
     *
     *  @param[in] pKey     - pointer to private key
     *  @param[in] privKeyFileName - private key filename
     */
    void writePrivateKey(
        const std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>& pKey,
        const std::string& privKeyFileName);

    /** @brief Add the specified CSR field with the data
     *  @param[in] x509Name - Structure used in setting certificate properties
     *  @param[in] field - field name
     *  @param[in] bytes - field value in bytes
     */
    void addEntry(X509_NAME* x509Name, const char* field,
                  const std::string& bytes);

    /** @brief Check if usage is extended key usage
     *  @param[in] usage - key usage value
     *  @return true if part of extended key usage
     */
    bool isExtendedKeyUsage(const std::string& usage);

    /** @brief Create CSR D-Bus object by reading the data in the CSR file
     *  @param[in] statis - SUCCESS/FAILURE In CSR generation.
     */
    void createCSRObject(const Status& status);

    /** @brief Write generated CSR data to file
     *
     *  @param[in] filePath - CSR file path.
     *  @param[in] x509Req - OpenSSL Request Pointer.
     */
    void writeCSR(
        const std::string& filePath,
        const std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>& x509Req);

    /** @brief Load certificate
     *  Load certificate and create certificate object
     */
    void createCertificates();

    /** @brief Create RSA private key file
     *  Create RSA private key file by generating rsa key if not created
     */
    void createRSAPrivateKeyFile();

    /** @brief Getting RSA private key
     *  Getting RSA private key from generated file
     *  @param[in]  keyBitLength - Key bit length
     *  @return     Pointer to RSA key
     */
    std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
        getRSAKeyPair(const int64_t keyBitLength);

    /** @brief Update certificate storage (remove outdated files, recreate
     * symbolic links, etc.).
     */
    void storageUpdate();

    /** @brief Check if provided certificate is unique across all certificates
     * on the internal list.
     *  @param[in] certFilePath - Path to the file with certificate for
     * uniqueness check.
     *  @param[in] certToDrop - Pointer to the certificate from the internal
     * list which should be not taken into account while uniqueness check.
     *  @return     Checking result. True if certificate is unique, false if
     * not.
     */
    bool isCertificateUnique(const std::string& certFilePath,
                             const Certificate* const certToDrop = nullptr);

    /** @brief sdbusplus handler */
    sdbusplus::bus::bus& bus;

    // sdevent Event handle
    sdeventplus::Event& event;

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

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

    /** @brief Unit name associated to the service **/
    std::string unitToRestart;

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

    /** @brief Collection of pointers to certificate */
    std::vector<std::unique_ptr<Certificate>> installedCerts;

    /** @brief pointer to CSR */
    std::unique_ptr<CSR> csrPtr = nullptr;

    /** @brief SDEventPlus child pointer added to event loop */
    std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr;

    /** @brief Watch on self signed certificates */
    std::unique_ptr<Watch> certWatchPtr = nullptr;

    /** @brief Parent path i.e certificate directory path */
    std::filesystem::path certParentInstallPath;

    /** @brief Certificate ID pool */
    uint64_t certIdCounter = 1;
};
} // namespace phosphor::certs
