/*
 *   Copyright (c) 2022 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 "DecoderCustomLog.h"

#include "../logging/Log.h"

#include <app/AttributeAccessInterface.h>
#include <app/MessageDef/InvokeRequestMessage.h>
#include <app/MessageDef/InvokeResponseMessage.h>
#include <app/MessageDef/ReportDataMessage.h>

#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>

#include <credentials/CertificationDeclaration.h>
#include <credentials/DeviceAttestationConstructor.h>
#include <credentials/DeviceAttestationVendorReserved.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>

#include <lib/core/CHIPTLV.h>
#include <lib/support/TypeTraits.h>

namespace {
template <typename T>
bool IsTag(const chip::TLV::TLVReader & reader, T tag)
{
    return chip::to_underlying(tag) == chip::TLV::TagNumFromTag(reader.GetTag());
}
} // namespace

namespace chip {
namespace trace {
namespace interaction_model {

using namespace logging;

CHIP_ERROR LogCertificateChainResponse(TLV::TLVReader & reader)
{
    app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    LogCertificate("DAC/PAI", value.certificate);

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogCertificationDeclaration(const ByteSpan & cd)
{
    auto scopedIndent = ScopedLogIndent("Certification Declaration");

    // TODO Add an option to load a TrustStore so the subjectKeyId can be extracted from the CMS envelope in order
    // to select the proper public key.
    ByteSpan kid;
    ReturnErrorOnFailure(Credentials::CMS_ExtractKeyId(cd, kid));

    Crypto::P256PublicKey verifyingKey;
    Credentials::CsaCdKeysTrustStore cdKeysTrustStore;
    ReturnErrorOnFailure(cdKeysTrustStore.LookupVerifyingKey(kid, verifyingKey));

    ByteSpan cdContentOut;
    ReturnErrorOnFailure(Credentials::CMS_Verify(cd, verifyingKey, cdContentOut));

    constexpr uint8_t kTag_FormatVersion       = 0;  /**< [ unsigned int ] Format version. */
    constexpr uint8_t kTag_VendorId            = 1;  /**< [ unsigned int ] Vedor identifier. */
    constexpr uint8_t kTag_ProductIdArray      = 2;  /**< [ array ] Product identifiers (each is unsigned int). */
    constexpr uint8_t kTag_DeviceTypeId        = 3;  /**< [ unsigned int ] Device Type identifier. */
    constexpr uint8_t kTag_CertificateId       = 4;  /**< [ UTF-8 string, length 19 ] Certificate identifier. */
    constexpr uint8_t kTag_SecurityLevel       = 5;  /**< [ unsigned int ] Security level. */
    constexpr uint8_t kTag_SecurityInformation = 6;  /**< [ unsigned int ] Security information. */
    constexpr uint8_t kTag_VersionNumber       = 7;  /**< [ unsigned int ] Version number. */
    constexpr uint8_t kTag_CertificationType   = 8;  /**< [ unsigned int ] Certification Type. */
    constexpr uint8_t kTag_DACOriginVendorId   = 9;  /**< [ unsigned int, optional ] DAC origin vendor identifier. */
    constexpr uint8_t kTag_DACOriginProductId  = 10; /**< [ unsigned int, optional ] DAC origin product identifier. */
    constexpr uint8_t kTag_AuthorizedPAAList   = 11; /**< [ array, optional ] Authorized PAA List. */

    TLV::TLVReader reader;
    reader.Init(cdContentOut);

    TLV::TLVType containerType = TLV::kTLVType_Structure;
    ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag()));
    ReturnErrorOnFailure(reader.EnterContainer(containerType));

    uint16_t value;
    CHIP_ERROR err = CHIP_NO_ERROR;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
        case kTag_FormatVersion:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Format Version", value);
            break;
        case kTag_VendorId:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Vendor Id", value);
            break;
        case kTag_ProductIdArray: {
            TLV::TLVType arrayType = TLV::kTLVType_Array;
            ReturnErrorOnFailure(reader.EnterContainer(arrayType));
            auto scopedProductIndent = ScopedLogIndent("Product Ids");
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                ReturnErrorOnFailure(reader.Get(value));
                Log("Product Id", value);
            }
            ReturnErrorOnFailure(reader.ExitContainer(arrayType));
            break;
        }
        case kTag_DeviceTypeId:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Device Type Id", value);
            break;
        case kTag_CertificateId: {
            CharSpan str;
            ReturnErrorOnFailure(reader.Get(str));
            Log("Certificate Id", str);
            break;
        }
        case kTag_SecurityLevel:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Security Level", value);
            break;
        case kTag_SecurityInformation:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Security Information", value);
            break;
        case kTag_VersionNumber:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Version Number", value);
            break;
        case kTag_CertificationType:
            ReturnErrorOnFailure(reader.Get(value));
            Log("Certification Type", value);
            break;
        case kTag_DACOriginVendorId:
            ReturnErrorOnFailure(reader.Get(value));
            Log("DAC Origin Vendor Id", value);
            break;
        case kTag_DACOriginProductId:
            ReturnErrorOnFailure(reader.Get(value));
            Log("DAC Origin Product Id", value);
            break;
        case kTag_AuthorizedPAAList: {
            TLV::TLVType arrayType = TLV::kTLVType_Array;
            ReturnErrorOnFailure(reader.EnterContainer(arrayType));
            auto scopedAuthorizedPAAIndent = ScopedLogIndent("Authorized PAAs");
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                ByteSpan str;
                ReturnErrorOnFailure(reader.Get(str));
                Log("Product Id", str);
            }
            ReturnErrorOnFailure(reader.ExitContainer(arrayType));
            break;
        }
        default:
            Log("<Unsupported Tag>");
            break;
        }
    }

    ReturnErrorOnFailure(reader.ExitContainer(containerType));

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogAttestationResponse(TLV::TLVReader & reader)
{
    app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    ByteSpan certificationDeclaration;
    ByteSpan attestationNonce;
    uint32_t timestamp;
    ByteSpan firmwareInfo;
    Credentials::DeviceAttestationVendorReservedDeconstructor vendorReserved;

    ReturnErrorOnFailure(Credentials::DeconstructAttestationElements(value.attestationElements, certificationDeclaration,
                                                                     attestationNonce, timestamp, firmwareInfo, vendorReserved));
    auto scopedIndent = ScopedLogIndentWithSize("Attestation Elements", value.attestationElements.size());
    ReturnErrorOnFailure(LogCertificationDeclaration(certificationDeclaration));
    Log("Attestation Nonce", attestationNonce);
    Log("Timestamp", timestamp);
    Log("Firmware Info", firmwareInfo);
    if (vendorReserved.GetNumberOfElements())
    {
        auto scopedVendorIndent = ScopedLogIndent("Vendors Reserved");
        Credentials::VendorReservedElement element;
        while (vendorReserved.GetNextVendorReservedElement(element) == CHIP_NO_ERROR)
        {
            auto scopedVendorReservedIndent = ScopedLogIndent("Vendor Reserved");
            Log("Vendor Id", element.vendorId);
            Log("Profile Number", element.profileNum);
            Log("Profile Data", element.vendorReservedData);
        }
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogCSRResponse(TLV::TLVReader & reader)
{
    app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    ByteSpan csr;
    ByteSpan csrNonce;
    ByteSpan vendorReserved1;
    ByteSpan vendorReserved2;
    ByteSpan vendorReserved3;

    ReturnErrorOnFailure(Credentials::DeconstructNOCSRElements(value.NOCSRElements, csr, csrNonce, vendorReserved1, vendorReserved2,
                                                               vendorReserved3));

    {
        auto scopedIndent = ScopedLogIndent("NOCSR Elements");
        Log("CSR", csr);
        Log("CSRNonce", csrNonce);
        Log("Vendor Reserved 1", vendorReserved1);
        Log("Vendor Reserved 2", vendorReserved2);
        Log("Vendor Reserved 3", vendorReserved3);
    }

    LogCertificateRequest("CSR", csr);

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogAddNOC(TLV::TLVReader & reader)
{
    app::Clusters::OperationalCredentials::Commands::AddNOC::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    LogCertificate("NOCValue", value.NOCValue);

    if (value.ICACValue.HasValue())
    {
        LogCertificate("ICACValue", value.ICACValue.Value());
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogAddTrustedRootCertificateRequest(TLV::TLVReader & reader)
{
    app::Clusters::OperationalCredentials::Commands::AddTrustedRootCertificate::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    LogCertificate("RCACValue", value.rootCertificate);

    return CHIP_NO_ERROR;
}

CHIP_ERROR LogNOCsAttribute(TLV::TLVReader & reader)
{
    if (reader.GetType() == TLV::kTLVType_Array)
    {
        return CHIP_NO_ERROR;
    }

    chip::app::Clusters::OperationalCredentials::Structs::NOCStruct::DecodableType value;
    ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));

    LogCertificate("NOC", value.noc);

    if (!value.icac.IsNull())
    {
        LogCertificate("ICAC", value.icac.Value());
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MaybeDecodeAttributeData(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    ClusterId clusterId;
    AttributeId attributeId;

    TLV::TLVType containerType;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (IsTag(reader, app::AttributeDataIB::Tag::kPath))
        {
            ReturnErrorOnFailure(reader.EnterContainer(containerType));
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                if (to_underlying(app::AttributePathIB::Tag::kCluster) == TLV::TagNumFromTag(reader.GetTag()))
                {
                    reader.Get(clusterId);
                }
                else if (to_underlying(app::AttributePathIB::Tag::kAttribute) == TLV::TagNumFromTag(reader.GetTag()))
                {
                    reader.Get(attributeId);
                }
            }
            ReturnErrorOnFailure(reader.ExitContainer(containerType));
        }
        else if (IsTag(reader, app::AttributeDataIB::Tag::kData))
        {
            switch (clusterId)
            {
            case app::Clusters::OperationalCredentials::Id:
                switch (attributeId)
                {
                case app::Clusters::OperationalCredentials::Attributes::NOCs::Id:
                    return LogNOCsAttribute(reader);
                default:
                    return CHIP_NO_ERROR;
                }
            default:
                return CHIP_NO_ERROR;
            }
        }
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MaybeDecodeCommandData(TLV::TLVReader & reader)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    ClusterId clusterId;
    CommandId commandId;

    TLV::TLVType containerType;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (IsTag(reader, app::CommandDataIB::Tag::kPath))
        {
            ReturnErrorOnFailure(reader.EnterContainer(containerType));
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                if (to_underlying(app::CommandPathIB::Tag::kClusterId) == TLV::TagNumFromTag(reader.GetTag()))
                {
                    reader.Get(clusterId);
                }
                else if (to_underlying(app::CommandPathIB::Tag::kCommandId) == TLV::TagNumFromTag(reader.GetTag()))
                {
                    reader.Get(commandId);
                }
            }
            ReturnErrorOnFailure(reader.ExitContainer(containerType));
        }
        else if (IsTag(reader, app::CommandDataIB::Tag::kFields))
        {
            switch (clusterId)
            {
            case app::Clusters::OperationalCredentials::Id:
                switch (commandId)
                {
                case app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::Id:
                    return LogCertificateChainResponse(reader);
                case app::Clusters::OperationalCredentials::Commands::AttestationResponse::Id:
                    return LogAttestationResponse(reader);
                case app::Clusters::OperationalCredentials::Commands::CSRResponse::Id:
                    return LogCSRResponse(reader);
                case app::Clusters::OperationalCredentials::Commands::AddNOC::Id:
                    return LogAddNOC(reader);
                case app::Clusters::OperationalCredentials::Commands::AddTrustedRootCertificate::Id:
                    return LogAddTrustedRootCertificateRequest(reader);
                default:
                    return CHIP_NO_ERROR;
                }
                break;
            default:
                break;
            }
        }
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MaybeDecodeNestedReadResponse(const uint8_t * data, size_t dataLen)
{
    TLV::TLVReader reader;
    reader.Init(data, dataLen);

    TLV::TLVType containerType = TLV::kTLVType_Structure;
    ReturnErrorOnFailure(reader.Next(containerType, TLV::AnonymousTag()));
    ReturnErrorOnFailure(reader.EnterContainer(containerType));

    CHIP_ERROR err = CHIP_NO_ERROR;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (IsTag(reader, app::ReportDataMessage::Tag::kAttributeReportIBs))
        {
            ReturnErrorOnFailure(reader.EnterContainer(containerType));
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                TLV::TLVType arrayType = TLV::kTLVType_Array;
                ReturnErrorOnFailure(reader.EnterContainer(arrayType));
                while (CHIP_NO_ERROR == (err = reader.Next()))
                {
                    if (IsTag(reader, app::AttributeReportIB::Tag::kAttributeData))
                    {
                        ReturnErrorOnFailure(reader.EnterContainer(containerType));
                        ReturnErrorOnFailure(MaybeDecodeAttributeData(reader));
                        ReturnErrorOnFailure(reader.ExitContainer(containerType));
                    }
                }
                ReturnErrorOnFailure(reader.ExitContainer(arrayType));
            }
            ReturnErrorOnFailure(reader.ExitContainer(containerType));
        }
    }

    return reader.ExitContainer(containerType);
}

CHIP_ERROR MaybeDecodeNestedCommandResponse(const uint8_t * data, size_t dataLen)
{
    TLV::TLVReader reader;
    reader.Init(data, dataLen);

    ReturnErrorOnFailure(reader.Next());

    TLV::TLVType containerType;
    ReturnErrorOnFailure(reader.EnterContainer(containerType));

    CHIP_ERROR err = CHIP_NO_ERROR;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (IsTag(reader, app::InvokeResponseMessage::Tag::kInvokeResponses))
        {
            ReturnErrorOnFailure(reader.EnterContainer(containerType));
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                ReturnErrorOnFailure(reader.EnterContainer(containerType));
                while (CHIP_NO_ERROR == (err = reader.Next()))
                {
                    if (IsTag(reader, app::InvokeResponseIB::Tag::kCommand))
                    {
                        ReturnErrorOnFailure(reader.EnterContainer(containerType));
                        ReturnErrorOnFailure(MaybeDecodeCommandData(reader));
                        ReturnErrorOnFailure(reader.ExitContainer(containerType));
                    }
                }
                ReturnErrorOnFailure(reader.ExitContainer(containerType));
            }
            ReturnErrorOnFailure(reader.ExitContainer(containerType));
        }
    }

    return reader.ExitContainer(containerType);
}

CHIP_ERROR MaybeDecodeNestedCommandRequest(const uint8_t * data, size_t dataLen)
{
    TLV::TLVReader reader;
    reader.Init(data, dataLen);

    ReturnErrorOnFailure(reader.Next());

    TLV::TLVType containerType;
    ReturnErrorOnFailure(reader.EnterContainer(containerType));

    CHIP_ERROR err = CHIP_NO_ERROR;
    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        if (IsTag(reader, app::InvokeRequestMessage::Tag::kInvokeRequests))
        {
            ReturnErrorOnFailure(reader.EnterContainer(containerType));
            while (CHIP_NO_ERROR == (err = reader.Next()))
            {
                ReturnErrorOnFailure(reader.EnterContainer(containerType));
                ReturnErrorOnFailure(MaybeDecodeCommandData(reader));
                ReturnErrorOnFailure(reader.ExitContainer(containerType));
            }
            ReturnErrorOnFailure(reader.ExitContainer(containerType));
        }
    }

    return reader.ExitContainer(containerType);
}

} // namespace interaction_model
} // namespace trace
} // namespace chip
