#pragma once
#ifdef BMCWEB_ENABLE_SSL

#include <openssl/bio.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>

#include <boost/asio/ssl/context.hpp>
#include <random>

namespace ensuressl
{
static void initOpenssl();
static EVP_PKEY *createEcKey();

// Trust chain related errors.`
inline bool isTrustChainError(int errnum)
{
    if ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ||
        (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ||
        (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) ||
        (errnum == X509_V_ERR_CERT_UNTRUSTED) ||
        (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))
    {
        return true;
    }
    else
    {
        return false;
    }
}

inline bool validateCertificate(X509 *const cert)
{
    // Create an empty X509_STORE structure for certificate validation.
    X509_STORE *x509Store = X509_STORE_new();
    if (!x509Store)
    {
        BMCWEB_LOG_ERROR << "Error occured during X509_STORE_new call";
        return false;
    }

    // Load Certificate file into the X509 structure.
    X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
    if (!storeCtx)
    {
        BMCWEB_LOG_ERROR << "Error occured during X509_STORE_CTX_new call";
        X509_STORE_free(x509Store);
        return false;
    }

    int errCode = X509_STORE_CTX_init(storeCtx, x509Store, cert, NULL);
    if (errCode != 1)
    {
        BMCWEB_LOG_ERROR << "Error occured during X509_STORE_CTX_init call";
        X509_STORE_CTX_free(storeCtx);
        X509_STORE_free(x509Store);
        return false;
    }

    errCode = X509_verify_cert(storeCtx);
    if (errCode == 1)
    {
        BMCWEB_LOG_INFO << "Certificate verification is success";
        X509_STORE_CTX_free(storeCtx);
        X509_STORE_free(x509Store);
        return true;
    }
    if (errCode == 0)
    {
        errCode = X509_STORE_CTX_get_error(storeCtx);
        X509_STORE_CTX_free(storeCtx);
        X509_STORE_free(x509Store);
        if (isTrustChainError(errCode))
        {
            BMCWEB_LOG_DEBUG << "Ignoring Trust Chain error. Reason: "
                             << X509_verify_cert_error_string(errCode);
            return true;
        }
        else
        {
            BMCWEB_LOG_ERROR << "Certificate verification failed. Reason: "
                             << X509_verify_cert_error_string(errCode);
            return false;
        }
    }

    BMCWEB_LOG_ERROR
        << "Error occured during X509_verify_cert call. ErrorCode: " << errCode;
    X509_STORE_CTX_free(storeCtx);
    X509_STORE_free(x509Store);
    return false;
}

inline bool verifyOpensslKeyCert(const std::string &filepath)
{
    bool privateKeyValid = false;
    bool certValid = false;

    std::cout << "Checking certs in file " << filepath << "\n";

    FILE *file = fopen(filepath.c_str(), "r");
    if (file != NULL)
    {
        EVP_PKEY *pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL);
        if (pkey != nullptr)
        {
            RSA *rsa = EVP_PKEY_get1_RSA(pkey);
            if (rsa != nullptr)
            {
                std::cout << "Found an RSA key\n";
                if (RSA_check_key(rsa) == 1)
                {
                    privateKeyValid = true;
                }
                else
                {
                    std::cerr << "Key not valid error number "
                              << ERR_get_error() << "\n";
                }
                RSA_free(rsa);
            }
            else
            {
                EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pkey);
                if (ec != nullptr)
                {
                    std::cout << "Found an EC key\n";
                    if (EC_KEY_check_key(ec) == 1)
                    {
                        privateKeyValid = true;
                    }
                    else
                    {
                        std::cerr << "Key not valid error number "
                                  << ERR_get_error() << "\n";
                    }
                    EC_KEY_free(ec);
                }
            }

            if (privateKeyValid)
            {
                // If the order is certificate followed by key in input file
                // then, certificate read will fail. So, setting the file
                // pointer to point beginning of file to avoid certificate and
                // key order issue.
                fseek(file, 0, SEEK_SET);

                X509 *x509 = PEM_read_X509(file, NULL, NULL, NULL);
                if (x509 == nullptr)
                {
                    std::cout << "error getting x509 cert " << ERR_get_error()
                              << "\n";
                }
                else
                {
                    certValid = validateCertificate(x509);
                    X509_free(x509);
                }
            }

            EVP_PKEY_free(pkey);
        }
        fclose(file);
    }
    return certValid;
}

inline void generateSslCertificate(const std::string &filepath)
{
    FILE *pFile = NULL;
    std::cout << "Generating new keys\n";
    initOpenssl();

    // std::cerr << "Generating RSA key";
    // EVP_PKEY *pRsaPrivKey = create_rsa_key();

    std::cerr << "Generating EC key\n";
    EVP_PKEY *pRsaPrivKey = createEcKey();
    if (pRsaPrivKey != nullptr)
    {
        std::cerr << "Generating x509 Certificate\n";
        // Use this code to directly generate a certificate
        X509 *x509;
        x509 = X509_new();
        if (x509 != nullptr)
        {
            // get a random number from the RNG for the certificate serial
            // number If this is not random, regenerating certs throws broswer
            // errors
            std::random_device rd;
            int serial = static_cast<int>(rd());

            ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);

            // not before this moment
            X509_gmtime_adj(X509_get_notBefore(x509), 0);
            // Cert is valid for 10 years
            X509_gmtime_adj(X509_get_notAfter(x509),
                            60L * 60L * 24L * 365L * 10L);

            // set the public key to the key we just generated
            X509_set_pubkey(x509, pRsaPrivKey);

            // get the subject name
            X509_NAME *name;
            name = X509_get_subject_name(x509);

            X509_NAME_add_entry_by_txt(
                name, "C", MBSTRING_ASC,
                reinterpret_cast<const unsigned char *>("US"), -1, -1, 0);
            X509_NAME_add_entry_by_txt(
                name, "O", MBSTRING_ASC,
                reinterpret_cast<const unsigned char *>("OpenBMC"), -1, -1, 0);
            X509_NAME_add_entry_by_txt(
                name, "CN", MBSTRING_ASC,
                reinterpret_cast<const unsigned char *>("testhost"), -1, -1, 0);
            // set the CSR options
            X509_set_issuer_name(x509, name);

            // Sign the certificate with our private key
            X509_sign(x509, pRsaPrivKey, EVP_sha256());

            pFile = fopen(filepath.c_str(), "wt");

            if (pFile != nullptr)
            {
                PEM_write_PrivateKey(pFile, pRsaPrivKey, NULL, NULL, 0, 0,
                                     NULL);

                PEM_write_X509(pFile, x509);
                fclose(pFile);
                pFile = NULL;
            }

            X509_free(x509);
        }

        EVP_PKEY_free(pRsaPrivKey);
        pRsaPrivKey = NULL;
    }

    // cleanup_openssl();
}

EVP_PKEY *createEcKey()
{
    EVP_PKEY *pKey = NULL;
    int eccgrp = 0;
    eccgrp = OBJ_txt2nid("prime256v1");

    EC_KEY *myecc = EC_KEY_new_by_curve_name(eccgrp);
    if (myecc != nullptr)
    {
        EC_KEY_set_asn1_flag(myecc, OPENSSL_EC_NAMED_CURVE);
        EC_KEY_generate_key(myecc);
        pKey = EVP_PKEY_new();
        if (pKey != nullptr)
        {
            if (EVP_PKEY_assign_EC_KEY(pKey, myecc))
            {
                /* pKey owns pRSA from now */
                if (EC_KEY_check_key(myecc) <= 0)
                {
                    fprintf(stderr, "EC_check_key failed.\n");
                }
            }
        }
    }
    return pKey;
}

void initOpenssl()
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();
    RAND_load_file("/dev/urandom", 1024);
#endif
}

inline void ensureOpensslKeyPresentAndValid(const std::string &filepath)
{
    bool pemFileValid = false;

    pemFileValid = verifyOpensslKeyCert(filepath);

    if (!pemFileValid)
    {
        std::cerr << "Error in verifying signature, regenerating\n";
        generateSslCertificate(filepath);
    }
}

inline std::shared_ptr<boost::asio::ssl::context>
    getSslContext(const std::string &ssl_pem_file)
{
    std::shared_ptr<boost::asio::ssl::context> mSslContext =
        std::make_shared<boost::asio::ssl::context>(
            boost::asio::ssl::context::tls_server);
    mSslContext->set_options(boost::asio::ssl::context::default_workarounds |
                             boost::asio::ssl::context::no_sslv2 |
                             boost::asio::ssl::context::no_sslv3 |
                             boost::asio::ssl::context::single_dh_use |
                             boost::asio::ssl::context::no_tlsv1 |
                             boost::asio::ssl::context::no_tlsv1_1);

    // m_ssl_context.set_verify_mode(boost::asio::ssl::verify_peer);
    mSslContext->use_certificate_file(ssl_pem_file,
                                      boost::asio::ssl::context::pem);
    mSslContext->use_private_key_file(ssl_pem_file,
                                      boost::asio::ssl::context::pem);

    // Set up EC curves to auto (boost asio doesn't have a method for this)
    // There is a pull request to add this.  Once this is included in an asio
    // drop, use the right way
    // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
    if (SSL_CTX_set_ecdh_auto(mSslContext->native_handle(), 1) != 1)
    {
        BMCWEB_LOG_ERROR << "Error setting tmp ecdh list\n";
    }

    std::string mozillaModern = "ECDHE-ECDSA-AES256-GCM-SHA384:"
                                "ECDHE-RSA-AES256-GCM-SHA384:"
                                "ECDHE-ECDSA-CHACHA20-POLY1305:"
                                "ECDHE-RSA-CHACHA20-POLY1305:"
                                "ECDHE-ECDSA-AES128-GCM-SHA256:"
                                "ECDHE-RSA-AES128-GCM-SHA256:"
                                "ECDHE-ECDSA-AES256-SHA384:"
                                "ECDHE-RSA-AES256-SHA384:"
                                "ECDHE-ECDSA-AES128-SHA256:"
                                "ECDHE-RSA-AES128-SHA256";

    if (SSL_CTX_set_cipher_list(mSslContext->native_handle(),
                                mozillaModern.c_str()) != 1)
    {
        BMCWEB_LOG_ERROR << "Error setting cipher list\n";
    }
    return mSslContext;
}
} // namespace ensuressl

#endif
