/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <filesystem>

#include "test_runner.h"
#include "certstore.h"

namespace dhtnet {
namespace test {

class CertStoreTest : public CppUnit::TestFixture
{
public:
    CertStoreTest()
    {
    }
    ~CertStoreTest() { }
    static std::string name() { return "certstore"; }
    void setUp();
    void tearDown();

    std::shared_ptr<tls::CertificateStore> aliceCertStore;
    std::shared_ptr<tls::TrustStore> aliceTrustStore;
private:
    void trustStoreTest();
    void getCertificateWithSplitted();
    void testBannedParent();

    CPPUNIT_TEST_SUITE(CertStoreTest);
    CPPUNIT_TEST(trustStoreTest);
    CPPUNIT_TEST(getCertificateWithSplitted);
    CPPUNIT_TEST(testBannedParent);
    CPPUNIT_TEST_SUITE_END();
};

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CertStoreTest, CertStoreTest::name());

void
CertStoreTest::setUp()
{
    aliceCertStore = std::make_shared<tls::CertificateStore>("aliceCertStore", nullptr);
    aliceTrustStore = std::make_shared<tls::TrustStore>(*aliceCertStore);
}

void
CertStoreTest::tearDown()
{
    std::filesystem::remove_all("aliceCertStore");
    aliceCertStore.reset();
    aliceTrustStore.reset();
}

void
CertStoreTest::trustStoreTest()
{
    auto ca = dht::crypto::generateIdentity("test CA");
    auto account = dht::crypto::generateIdentity("test account", ca, 4096, true);
    auto device = dht::crypto::generateIdentity("test device", account);
    auto device2 = dht::crypto::generateIdentity("test device 2", account);
    auto storeSize = aliceCertStore->getPinnedCertificates().size();
    auto id = ca.second->getId().toString();
    auto pinned = aliceCertStore->getPinnedCertificates();
    CPPUNIT_ASSERT(std::find_if(pinned.begin(), pinned.end(), [&](auto v) { return v == id; })
                   == pinned.end());

    // Test certificate status
    auto certAllowed = aliceTrustStore->getCertificatesByStatus(
        dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    CPPUNIT_ASSERT(
        std::find_if(certAllowed.begin(), certAllowed.end(), [&](auto v) { return v == id; })
        == certAllowed.end());
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(id)
                   == dhtnet::tls::TrustStore::PermissionStatus::UNDEFINED);
    aliceTrustStore->setCertificateStatus(ca.second, dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    certAllowed = aliceTrustStore->getCertificatesByStatus(
        dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    CPPUNIT_ASSERT(
        std::find_if(certAllowed.begin(), certAllowed.end(), [&](auto v) { return v == id; })
        != certAllowed.end());
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(id)
                   == dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    aliceTrustStore->setCertificateStatus(ca.second, dhtnet::tls::TrustStore::PermissionStatus::UNDEFINED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(id)
                   == dhtnet::tls::TrustStore::PermissionStatus::UNDEFINED);
    aliceTrustStore->setCertificateStatus(ca.second, dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(id)
                   == dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);

    // Test getPinnedCertificates
    pinned = aliceCertStore->getPinnedCertificates();
    CPPUNIT_ASSERT(pinned.size() == storeSize + 2);
    CPPUNIT_ASSERT(std::find_if(pinned.begin(), pinned.end(), [&](auto v) { return v == id; })
                   != pinned.end());

    // Test findCertificateByUID & findIssuer
    CPPUNIT_ASSERT(!aliceCertStore->findCertificateByUID("NON_EXISTING_ID"));
    auto cert = aliceCertStore->findCertificateByUID(id);
    CPPUNIT_ASSERT(cert);
    auto issuer = aliceCertStore->findIssuer(cert);
    CPPUNIT_ASSERT(issuer);
    CPPUNIT_ASSERT(issuer->getId().toString() == id);

    // Test is allowed
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*ca.second));
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*device.second));

    // Ban device
    aliceTrustStore->setCertificateStatus(device.second, dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(device.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(id)
                   == dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);

    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*ca.second));
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*device.second));

    // Ban account
    aliceTrustStore->setCertificateStatus(account.second, dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(account.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*ca.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*device2.second));

    // Unban account
    aliceTrustStore->setCertificateStatus(account.second,
                                    dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(account.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::ALLOWED);
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*ca.second));
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(aliceTrustStore->isAllowed(*device2.second));

    // Ban CA
    aliceTrustStore->setCertificateStatus(ca.second, dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(ca.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*ca.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*device2.second));

    aliceTrustStore->setCertificateStatus(ca.second, dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(ca.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::BANNED);

    // Test unpin
    aliceCertStore->unpinCertificate(id);
    pinned = aliceCertStore->getPinnedCertificates();
    CPPUNIT_ASSERT(std::find_if(pinned.begin(), pinned.end(), [&](auto v) { return v == id; })
                   == pinned.end());

    // Test statusToStr
    /*CPPUNIT_ASSERT(strcmp(dhtnet::tls::statusToStr(dhtnet::tls::TrustStatus::TRUSTED),
                          libdhtnet::Certificate::TrustStatus::TRUSTED)
                   == 0);
    CPPUNIT_ASSERT(strcmp(dhtnet::tls::statusToStr(dhtnet::tls::TrustStatus::UNTRUSTED),
                          libdhtnet::Certificate::TrustStatus::UNTRUSTED)
                   == 0);*/
}

void
CertStoreTest::getCertificateWithSplitted()
{
    auto ca = dht::crypto::generateIdentity("test CA");
    auto account = dht::crypto::generateIdentity("test account", ca, 4096, true);
    auto device = dht::crypto::generateIdentity("test device", account);

    auto caCert = std::make_shared<dht::crypto::Certificate>(ca.second->toString(false));
    auto accountCert = std::make_shared<dht::crypto::Certificate>(account.second->toString(false));
    auto devicePartialCert = std::make_shared<dht::crypto::Certificate>(
        device.second->toString(false));

    aliceCertStore->pinCertificate(caCert);
    aliceCertStore->pinCertificate(accountCert);
    aliceCertStore->pinCertificate(devicePartialCert);

    auto fullCert = aliceCertStore->getCertificate(device.second->getId().toString());
    CPPUNIT_ASSERT(fullCert->issuer && fullCert->issuer->getUID() == accountCert->getUID());
    CPPUNIT_ASSERT(fullCert->issuer->issuer
                   && fullCert->issuer->issuer->getUID() == caCert->getUID());
}

void
CertStoreTest::testBannedParent()
{
    auto ca = dht::crypto::generateIdentity("test CA");
    auto account = dht::crypto::generateIdentity("test account", ca, 4096, true);
    auto device = dht::crypto::generateIdentity("test device", account);
    auto device2 = dht::crypto::generateIdentity("test device 2", account);
    auto id = ca.second->getId().toString();
    auto pinned = aliceCertStore ->getPinnedCertificates();
    CPPUNIT_ASSERT(std::find_if(pinned.begin(), pinned.end(), [&](auto v) { return v == id; })
                   == pinned.end());

    // Ban account
    aliceTrustStore->setCertificateStatus(account.second, dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(aliceTrustStore->getCertificateStatus(account.second->getId().toString())
                   == dhtnet::tls::TrustStore::PermissionStatus::BANNED);
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*account.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*device2.second));
    CPPUNIT_ASSERT(not aliceTrustStore->isAllowed(*device.second));
}


} // namespace test
} // namespace dhtnet

JAMI_TEST_RUNNER(dhtnet::test::CertStoreTest::name());
