/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#include <ESP8266WebServerSecure.h>

#include <eCxx/Platform/NodeMCU/WebServerSSL.h>

#include "WebServer.tpp"


namespace eCxx {


//
// Explicit instantiation of the SLL web server class
//
template class BasicWebServer< esp8266webserver::ESP8266WebServerTemplate<BearSSL::WiFiServerSecure> >;


//
// A simple and thin wrapper class for NodeMCU's ESP8266WebServerSecure class so that the public API
// will appear more consistent with other eCxx library APIs
//
WebServerSSL::WebServerSSL(uint16_t port)
: BasicWebServer<BearSSL::ESP8266WebServerSecure>(port)
, _chain     (nullptr)
, _privateKey(nullptr)
, _clientTA  (nullptr)
{}


WebServerSSL::~WebServerSSL()
{
    clearCertificate();
    clearClientTA();
}


bool WebServerSSL::setRSACertificate(PGMCharPointer chain, PGMCharPointer privateKey)
{
    clearCertificate();

    _chain = new(eCxx::nothrow) BearSSL::X509List(chain.p);
    if(!_chain) return false;

    _privateKey = new(eCxx::nothrow) BearSSL::PrivateKey(privateKey.p);
    if(!_privateKey) {
        delete _chain;
        _chain = nullptr;
        return false;
    }

    _webServer->getServer().setRSACert(_chain, _privateKey);

    return true;
}


bool WebServerSSL::setEllipticCurveCertificate(PGMCharPointer chain, PGMCharPointer privateKey, CertIssuerKeyType certIssuerKeyType)
{
    clearCertificate();

    _chain = new(eCxx::nothrow) BearSSL::X509List(chain.p);
    if(!_chain) return false;

    _privateKey = new(eCxx::nothrow) BearSSL::PrivateKey(privateKey.p);
    if(!_privateKey) {
        delete _chain;
        _chain = nullptr;
        return false;
    }

    _webServer->getServer().setECCert(_chain, static_cast<uint8_t>(certIssuerKeyType), _privateKey);

    return true;
}


bool WebServerSSL::setClientTrustAnchor(PGMCharPointer clientTA)
{
    clearClientTA();

    _clientTA = new(eCxx::nothrow) BearSSL::X509List(clientTA.p);
    if(!_clientTA) return false;

    _webServer->getServer().setClientTrustAnchor(_clientTA);

    return true;
}


void WebServerSSL::clearCertificate()
{
    if(_chain     ) delete _chain;
    if(_privateKey) delete _privateKey;

    _chain      = nullptr;
    _privateKey = nullptr;
}


void WebServerSSL::clearClientTA()
{
    if(_clientTA) delete _clientTA;

    _clientTA = nullptr;
}


} // namespace eCxx
