/*
 *
 *    Copyright (c) 2025 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,

 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <app/clusters/tls-certificate-management-server/CertificateTableImpl.h>

#include <app/InteractionModelEngine.h>
#include <app/util/mock/Constants.h>
#include <app/util/mock/MockNodeConfig.h>
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
#include <lib/support/TestPersistentStorageDelegate.h>

#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <pw_unit_test/framework.h>

using namespace chip;
using namespace chip::Testing;
using namespace chip::app::DataModel;
using namespace chip::app::Storage;
using namespace chip::app::Storage::Data;
using namespace chip::app::Clusters::Tls;
using namespace chip::app::Clusters::TlsCertificateManagement;
using namespace chip::app::Clusters::TlsCertificateManagement::Structs;
using chip::TLV::EstimateStructOverhead;
using namespace chip::Crypto;
using namespace chip::Credentials;

namespace TestCertificates {

static constexpr uint16_t kSpecMaxCertBytes = 3000;

struct InlineBufferedRootCert : CertificateTable::BufferedRootCert
{
    PersistenceBuffer<CHIP_CONFIG_TLS_PERSISTED_ROOT_CERT_BYTES> buffer;
    InlineBufferedRootCert() : CertificateTable::BufferedRootCert(buffer) {}
};

struct InlineBufferedClientCert : CertificateTable::BufferedClientCert
{
    PersistenceBuffer<CHIP_CONFIG_TLS_PERSISTED_CLIENT_CERT_BYTES> buffer;
    InlineBufferedClientCert() : CertificateTable::BufferedClientCert(buffer) {}
};

// Test constants
constexpr FabricIndex kFabric1 = 1;
constexpr FabricIndex kFabric2 = 2;

class TestCertificateTableImpl : public ::testing::Test
{
public:
    static void SetUpTestSuite()
    {
        mpTestStorage = new chip::TestPersistentStorageDelegate;
        ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR);
        ASSERT_NE(mpTestStorage, nullptr);
        ASSERT_EQ(sCertificateTable.Init(*mpTestStorage), CHIP_NO_ERROR);
        ASSERT_EQ(sCertificateTable.SetEndpoint(kMockEndpoint1), CHIP_NO_ERROR);
        app::InteractionModelEngine::GetInstance()->SetDataModelProvider(&app::CodegenDataModelProvider::Instance());
    }

    static void TearDownTestSuite()
    {
        sCertificateTable.Finish();
        delete mpTestStorage;
        mpTestStorage = nullptr;
        Platform::MemoryShutdown();
    }

    static void ResetCertificateTable()
    {
        EXPECT_SUCCESS(sCertificateTable.RemoveFabric(kFabric1));
        EXPECT_SUCCESS(sCertificateTable.RemoveFabric(kFabric2));
    }

protected:
    static CertificateTableImpl sCertificateTable;
    static chip::TestPersistentStorageDelegate * mpTestStorage;
};

CertificateTableImpl TestCertificateTableImpl::sCertificateTable;
chip::TestPersistentStorageDelegate * TestCertificateTableImpl::mpTestStorage = nullptr;

TEST_F(TestCertificateTableImpl, TestRootCertificateOperations)
{
    ResetCertificateTable();

    const uint8_t byteBuf[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF };
    ByteSpan testCert(byteBuf);
    auto buffer = std::make_unique<InlineBufferedRootCert>();
    Optional<TLSCAID> id;

    // Add a root certificate
    EXPECT_EQ(sCertificateTable.UpsertRootCertificateEntry(kFabric1, id, buffer->buffer, testCert), CHIP_NO_ERROR);
    EXPECT_TRUE(id.HasValue());
    TLSCAID certId = id.Value();

    // Check if it exists
    EXPECT_EQ(sCertificateTable.HasRootCertificateEntry(kFabric1, certId), CHIP_NO_ERROR);

    // Get the certificate
    auto entry = std::make_unique<InlineBufferedRootCert>();
    EXPECT_EQ(sCertificateTable.GetRootCertificateEntry(kFabric1, certId, *entry), CHIP_NO_ERROR);
    EXPECT_TRUE(entry->mCert.certificate.Value().data_equal(testCert));

    // Remove the certificate
    EXPECT_EQ(sCertificateTable.RemoveRootCertificate(kFabric1, certId), CHIP_NO_ERROR);

    // Check that it's gone
    EXPECT_EQ(sCertificateTable.HasRootCertificateEntry(kFabric1, certId), CHIP_ERROR_NOT_FOUND);
}

TEST_F(TestCertificateTableImpl, TestClientCertificateOperations)
{
    ResetCertificateTable();

    const uint8_t byteBuf[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF };
    ByteSpan nonce(byteBuf);
    auto certBuffer = std::make_unique<InlineBufferedClientCert>();
    Optional<TLSCCDID> id;

    auto csr_buf = std::make_unique<std::array<uint8_t, kSpecMaxCertBytes>>();
    MutableByteSpan csr(*csr_buf);
    uint8_t nonce_sig_buf[Crypto::P256ECDSASignature::Capacity()];
    MutableByteSpan nonceSignature(nonce_sig_buf);

    // Prepare a client certificate
    EXPECT_EQ(sCertificateTable.PrepareClientCertificate(kFabric1, nonce, certBuffer->buffer, id, csr, nonceSignature),
              CHIP_NO_ERROR);
    EXPECT_TRUE(id.HasValue());
    TLSCCDID certId = id.Value();

    // Check if it exists
    EXPECT_EQ(sCertificateTable.HasClientCertificateEntry(kFabric1, certId), CHIP_NO_ERROR);

    // Remove the certificate
    EXPECT_EQ(sCertificateTable.RemoveClientCertificate(kFabric1, certId), CHIP_NO_ERROR);

    // Check that it's gone
    EXPECT_EQ(sCertificateTable.HasClientCertificateEntry(kFabric1, certId), CHIP_ERROR_NOT_FOUND);
}

TEST_F(TestCertificateTableImpl, TestFabricRemoval)
{
    ResetCertificateTable();

    const uint8_t byteBuf[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF };
    ByteSpan rootCert(byteBuf);
    auto rootBuffer = std::make_unique<InlineBufferedRootCert>();
    Optional<TLSCAID> rootId;
    EXPECT_EQ(sCertificateTable.UpsertRootCertificateEntry(kFabric1, rootId, rootBuffer->buffer, rootCert), CHIP_NO_ERROR);

    const uint8_t nonceByteBuf[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF };
    ByteSpan nonce(nonceByteBuf);
    auto clientBuffer = std::make_unique<InlineBufferedClientCert>();
    Optional<TLSCCDID> clientId;
    auto csr_buf = std::make_unique<std::array<uint8_t, kSpecMaxCertBytes>>();
    MutableByteSpan csr(*csr_buf);
    uint8_t nonce_sig_buf[Crypto::P256ECDSASignature::Capacity()];
    MutableByteSpan nonceSignature(nonce_sig_buf);
    EXPECT_EQ(sCertificateTable.PrepareClientCertificate(kFabric1, nonce, clientBuffer->buffer, clientId, csr, nonceSignature),
              CHIP_NO_ERROR);

    uint8_t count;
    EXPECT_EQ(sCertificateTable.GetRootCertificateCount(kFabric1, count), CHIP_NO_ERROR);
    EXPECT_EQ(count, 1);
    EXPECT_EQ(sCertificateTable.GetClientCertificateCount(kFabric1, count), CHIP_NO_ERROR);
    EXPECT_EQ(count, 1);

    EXPECT_EQ(sCertificateTable.RemoveFabric(kFabric1), CHIP_NO_ERROR);

    EXPECT_EQ(sCertificateTable.GetRootCertificateCount(kFabric1, count), CHIP_NO_ERROR);
    EXPECT_EQ(count, 0);
    EXPECT_EQ(sCertificateTable.GetClientCertificateCount(kFabric1, count), CHIP_NO_ERROR);
    EXPECT_EQ(count, 0);
}

TEST_F(TestCertificateTableImpl, TestRootCertificateIteration)
{
    ResetCertificateTable();

    const uint8_t byteBuf1[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF, 0xA };
    const uint8_t byteBuf2[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF, 0xB };
    ByteSpan rootCert1(byteBuf1);
    ByteSpan rootCert2(byteBuf2);
    auto rootBuffer1 = std::make_unique<InlineBufferedRootCert>();
    auto rootBuffer2 = std::make_unique<InlineBufferedRootCert>();
    Optional<TLSCAID> rootId1;
    Optional<TLSCAID> rootId2;

    EXPECT_EQ(sCertificateTable.UpsertRootCertificateEntry(kFabric1, rootId1, rootBuffer1->buffer, rootCert1), CHIP_NO_ERROR);
    EXPECT_EQ(sCertificateTable.UpsertRootCertificateEntry(kFabric1, rootId2, rootBuffer2->buffer, rootCert2), CHIP_NO_ERROR);
    EXPECT_NE(rootId1, rootId2);

    uint8_t count   = 0;
    auto certBuffer = std::make_unique<InlineBufferedRootCert>();
    auto iterFn     = [&](auto & iterator) {
        while (iterator.Next(certBuffer->GetCert()))
        {
            count++;
        }
        return CHIP_NO_ERROR;
    };

    EXPECT_EQ(sCertificateTable.IterateRootCertificates(kFabric1, *certBuffer, iterFn), CHIP_NO_ERROR);
    EXPECT_EQ(count, 2);
}

CHIP_ERROR GetTestCert(MutableByteSpan & signedCert, InlineBufferedClientCert & cert, const ByteSpan & csr)
{
    ChipDN ica_dn;
    ReturnErrorOnFailure(ica_dn.AddAttribute_MatterICACId(0xABCDABCDABCDABCD));
    ChipDN issuer_dn;
    ReturnErrorOnFailure(issuer_dn.AddAttribute_MatterRCACId(0x43215678FEDCABCD));
    X509CertRequestParams params = { 1234, 631161876, 729942000, ica_dn, issuer_dn };
    P256PublicKey pubkey;
    ReturnErrorOnFailure(VerifyCertificateSigningRequest(csr.data(), csr.size(), pubkey));
    Crypto::P256Keypair testPair;
    ReturnErrorOnFailure(testPair.Initialize(Crypto::ECPKeyTarget::ECDSA));
    ReturnErrorOnFailure(NewICAX509Cert(params, pubkey, testPair, signedCert));
    cert.GetCert().clientCertificate.SetValue(signedCert);
    return CHIP_NO_ERROR;
}

TEST_F(TestCertificateTableImpl, TestClientCertificateIteration)
{
    ResetCertificateTable();

    const uint8_t byteBuf[] = { 0x1, 0x2, 0x3, 0x4, 0x8, 0xF, 0xFF };
    ByteSpan nonce(byteBuf);
    auto certBuffer1 = std::make_unique<InlineBufferedClientCert>();
    auto certBuffer2 = std::make_unique<InlineBufferedClientCert>();
    Optional<TLSCAID> clientId1;
    Optional<TLSCAID> clientId2;

    auto csr_buf = std::make_unique<std::array<uint8_t, kSpecMaxCertBytes>>();
    MutableByteSpan csr(*csr_buf);
    uint8_t nonceSigBuff[Crypto::P256ECDSASignature::Capacity()];
    MutableByteSpan nonceSignature(nonceSigBuff);

    uint8_t signedCert[kMaxDERCertLength];
    MutableByteSpan signedCertSpan(signedCert);
    // Prepare client certificates
    EXPECT_EQ(sCertificateTable.PrepareClientCertificate(kFabric1, nonce, certBuffer1->buffer, clientId1, csr, nonceSignature),
              CHIP_NO_ERROR);
    EXPECT_EQ(GetTestCert(signedCertSpan, *certBuffer1, csr), CHIP_NO_ERROR);
    EXPECT_EQ(
        sCertificateTable.UpdateClientCertificateEntry(kFabric1, clientId1.Value(), certBuffer1->buffer, certBuffer1->GetCert()),
        CHIP_NO_ERROR);

    csr            = MutableByteSpan(*csr_buf);
    signedCertSpan = MutableByteSpan(signedCert);
    EXPECT_EQ(sCertificateTable.PrepareClientCertificate(kFabric1, nonce, certBuffer2->buffer, clientId2, csr, nonceSignature),
              CHIP_NO_ERROR);
    EXPECT_EQ(GetTestCert(signedCertSpan, *certBuffer2, csr), CHIP_NO_ERROR);
    EXPECT_EQ(
        sCertificateTable.UpdateClientCertificateEntry(kFabric1, clientId2.Value(), certBuffer2->buffer, certBuffer2->GetCert()),
        CHIP_NO_ERROR);
    EXPECT_NE(clientId1, clientId2);

    uint8_t count   = 0;
    auto certBuffer = std::make_unique<InlineBufferedClientCert>();
    auto iterFn     = [&](auto & iterator) {
        while (iterator.Next(certBuffer->mCertWithKey))
        {
            count++;
        }
        return CHIP_NO_ERROR;
    };

    EXPECT_EQ(sCertificateTable.IterateClientCertificates(kFabric1, *certBuffer, iterFn), CHIP_NO_ERROR);
    EXPECT_EQ(count, 2);
}

} // namespace TestCertificates
