#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_t& 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& pKeyCurveId);

    /** @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_t& 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
