/*
 *
 *    Copyright (c) 2025 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 <pw_unit_test/framework.h>

#include <controller/CommissioneeDeviceProxy.h>
#include <credentials/DeviceAttestationConstructor.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <credentials/attestation_verifier/TestDACRevocationDelegateImpl.h>
#include <credentials/tests/CHIPAttCert_test_vectors.h>
#include <credentials/tests/CHIPCert_unit_test_vectors.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/Span.h>

using namespace chip;
using namespace chip::Credentials;
using namespace chip::TestCerts;

struct TestDeviceAttestationVerifier : public ::testing::Test
{
    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
};

// Test that AttestationDeviceInfo correctly copies fields from AttestationInfo
TEST_F(TestDeviceAttestationVerifier, AttestationDeviceInfoCopiesFields)
{
    // Use real DER test vectors for PAI/DAC and a valid 32-byte nonce
    const ByteSpan paiSpan = TestCerts::sTestCert_PAI_FFF1_8000_Cert;
    const ByteSpan dacSpan = TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert;
    uint8_t nonceData[32]  = {
        0xe0, 0x42, 0x1b, 0x91, 0xc6, 0xfd, 0xcd, 0xb4, 0x0e, 0x2a, 0x4d, 0x2c, 0xf3, 0x1d, 0xb2, 0xb4,
        0xe1, 0x8b, 0x41, 0x1b, 0x1d, 0x3a, 0xd4, 0xd1, 0x2a, 0x9d, 0x90, 0xaa, 0x8e, 0x52, 0xfa, 0xe2,
    };
    ByteSpan nonceSpan(nonceData);

    // Prepare attestation elements TLV with a minimal CertificateDeclaration
    uint8_t cdData[32] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
    uint8_t tlvBuf[128];
    chip::TLV::TLVWriter writer;
    writer.Init(tlvBuf, sizeof(tlvBuf));
    chip::TLV::TLVType outerType;

    // Add attestation elements to the TLV structure
    CHIP_ERROR err = writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerType);
    ASSERT_EQ(err, CHIP_NO_ERROR);
    writer.Put(chip::TLV::ContextTag(1), ByteSpan(cdData));
    writer.Put(chip::TLV::ContextTag(2), ByteSpan(nonceData));
    writer.Put(chip::TLV::ContextTag(3), static_cast<uint32_t>(0)); // Timestamp
    writer.Put(chip::TLV::ContextTag(4), ByteSpan());               // FirmwareInfo
    writer.Put(chip::TLV::ContextTag(5), ByteSpan());               // VendorReserved
    err = writer.EndContainer(outerType);
    ASSERT_EQ(err, CHIP_NO_ERROR);

    ByteSpan attestationElementsSpan(tlvBuf, writer.GetLengthWritten());

    // Construct AttestationInfo
    DeviceAttestationVerifier::AttestationInfo attestationInfo(attestationElementsSpan,
                                                               nonceSpan, // attestationChallenge
                                                               nonceSpan, // attestationSignature
                                                               paiSpan, dacSpan,
                                                               nonceSpan, // certificationDeclarationBuffer
                                                               VendorId(0x1234),
                                                               0x5678 // productId
    );

    // Create AttestationDeviceInfo
    DeviceAttestationVerifier::AttestationDeviceInfo deviceInfo(attestationInfo);

    // Verify that vendorId and productId were copied correctly
    EXPECT_EQ(deviceInfo.BasicInformationVendorId(), VendorId(0x1234));
    EXPECT_EQ(deviceInfo.BasicInformationProductId(), 0x5678); // productId

    // Verify that the PAI, DAC, and CD buffers were copied correctly
    ByteSpan copiedPai = deviceInfo.paiDerBuffer();
    EXPECT_TRUE(copiedPai.data_equal(paiSpan));

    // Verify that the DAC buffer was copied correctly
    ByteSpan copiedDac = deviceInfo.dacDerBuffer();
    EXPECT_TRUE(copiedDac.data_equal(dacSpan));

    // Verify that the CD buffer was copied correctly
    ASSERT_TRUE(deviceInfo.cdBuffer().HasValue());
    ByteSpan copiedCd = deviceInfo.cdBuffer().Value();
    EXPECT_TRUE(copiedCd.data_equal(ByteSpan(cdData)));
}

// Test that setting the DeviceAttestationVerifier to nullptr does not change the current verifier
TEST_F(TestDeviceAttestationVerifier, SetDeviceAttestationVerifierNullptrArgument)
{
    DeviceAttestationVerifier * original = GetDeviceAttestationVerifier();
    SetDeviceAttestationVerifier(nullptr);
    EXPECT_EQ(GetDeviceAttestationVerifier(), original);
}

// Test that setting a revocation delegate works as expected
TEST_F(TestDeviceAttestationVerifier, SetRevocationDelegate)
{
    // Create a minimal AttestationTrustStore with a dummy certificate
    static uint8_t dummyCert[1]       = { 0x00 };
    static const ByteSpan certSpans[] = { ByteSpan(dummyCert) };
    ArrayAttestationTrustStore trustStore(certSpans, 1);
    DefaultDACVerifier verifier(&trustStore);

    // Check the initial state of the revocation delegate
    EXPECT_EQ(verifier.SetRevocationDelegate(nullptr), CHIP_NO_ERROR);
}

// Test CheckForRevokedDACChain with successful revocation check
TEST_F(TestDeviceAttestationVerifier, CheckForRevokedDACChainSuccess)
{
    // Create a minimal AttestationTrustStore with a dummy certificate
    static uint8_t dummyCert[1]       = { 0x00 };
    static const ByteSpan certSpans[] = { ByteSpan(dummyCert) };
    ArrayAttestationTrustStore trustStore(certSpans, 1);
    DefaultDACVerifier verifier(&trustStore);

    // Create a test revocation delegate that returns success (no revocation data set)
    TestDACRevocationDelegateImpl revocationDelegate;
    verifier.SetRevocationDelegate(&revocationDelegate);

    // Prepare dummy attestation data
    uint8_t testData[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    ByteSpan testSpan(testData);

    // Create AttestationInfo using the constructor with all required arguments
    DeviceAttestationVerifier::AttestationInfo attestationInfo(testSpan, testSpan, testSpan, testSpan, testSpan, testSpan,
                                                               VendorId(0x1234), 0x5678);

    // Test that the callback is called with success result
    AttestationVerificationResult result = AttestationVerificationResult::kInternalError;
    chip::Callback::Callback<DeviceAttestationVerifier::OnAttestationInformationVerification> callback(
        [](void * context, const DeviceAttestationVerifier::AttestationInfo &, AttestationVerificationResult verificationResult) {
            AttestationVerificationResult * resultPtr = static_cast<AttestationVerificationResult *>(context);
            *resultPtr                                = verificationResult;
        },
        &result);

    verifier.CheckForRevokedDACChain(attestationInfo, &callback);
    EXPECT_EQ(result, AttestationVerificationResult::kSuccess);
}

// Test CheckForRevokedDACChain with empty revocation data (should return success)
TEST_F(TestDeviceAttestationVerifier, CheckForRevokedDACChainEmptyRevocationData)
{
    // Create a minimal AttestationTrustStore with a dummy certificate
    static uint8_t dummyCert[1]       = { 0x00 };
    static const ByteSpan certSpans[] = { ByteSpan(dummyCert) };
    ArrayAttestationTrustStore trustStore(certSpans, 1);
    DefaultDACVerifier verifier(&trustStore);

    // Create a test revocation delegate with empty revocation data
    TestDACRevocationDelegateImpl revocationDelegate;
    revocationDelegate.SetDeviceAttestationRevocationData("[]"); // Empty revocation list
    verifier.SetRevocationDelegate(&revocationDelegate);

    // Prepare dummy attestation data
    uint8_t testData[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    ByteSpan testSpan(testData);

    // Create AttestationInfo using the constructor with all required arguments
    DeviceAttestationVerifier::AttestationInfo attestationInfo(testSpan, testSpan, testSpan, testSpan, testSpan, testSpan,
                                                               VendorId(0x1234), 0x5678);

    // Test that the callback is called with success result (empty revocation list)
    AttestationVerificationResult result = AttestationVerificationResult::kInternalError;
    chip::Callback::Callback<DeviceAttestationVerifier::OnAttestationInformationVerification> callback(
        [](void * context, const DeviceAttestationVerifier::AttestationInfo &, AttestationVerificationResult verificationResult) {
            AttestationVerificationResult * resultPtr = static_cast<AttestationVerificationResult *>(context);
            *resultPtr                                = verificationResult;
        },
        &result);

    verifier.CheckForRevokedDACChain(attestationInfo, &callback);
    EXPECT_EQ(result, AttestationVerificationResult::kSuccess);

    // Clean up
    revocationDelegate.ClearDeviceAttestationRevocationData();
}

// Test CheckForRevokedDACChain without revocation delegate (should skip checks)
TEST_F(TestDeviceAttestationVerifier, CheckForRevokedDACChainNoDelegate)
{
    // Create a minimal AttestationTrustStore with a dummy certificate
    static uint8_t dummyCert[1]       = { 0x00 };
    static const ByteSpan certSpans[] = { ByteSpan(dummyCert) };
    ArrayAttestationTrustStore trustStore(certSpans, 1);
    DefaultDACVerifier verifier(&trustStore);

    // Don't set a revocation delegate (should be nullptr by default)

    // Prepare dummy attestation data
    uint8_t testData[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
    ByteSpan testSpan(testData);

    // Create AttestationInfo using the constructor with all required arguments
    DeviceAttestationVerifier::AttestationInfo attestationInfo(testSpan, testSpan, testSpan, testSpan, testSpan, testSpan,
                                                               VendorId(0x1234), 0x5678);

    // Test that the callback is called with success result (skipped)
    AttestationVerificationResult result = AttestationVerificationResult::kInternalError;
    chip::Callback::Callback<DeviceAttestationVerifier::OnAttestationInformationVerification> callback(
        [](void * context, const DeviceAttestationVerifier::AttestationInfo &, AttestationVerificationResult verificationResult) {
            AttestationVerificationResult * resultPtr = static_cast<AttestationVerificationResult *>(context);
            *resultPtr                                = verificationResult;
        },
        &result);

    verifier.CheckForRevokedDACChain(attestationInfo, &callback);
    EXPECT_EQ(result, AttestationVerificationResult::kSuccess);
}
