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

#include <credentials/CHIPCert.h>
#include <credentials/CertificationDeclaration.h>
#include <credentials/examples/ExampleDACs.h>
#include <credentials/examples/ExamplePAI.h>
#include <crypto/CHIPCryptoPAL.h>
#include <json/json.h>
#include <lib/core/CHIPError.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/Span.h>

#include <fstream>

//-> format_version = 1
//-> vendor_id = 0xFFF1
//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B,
// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A,
// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029,
// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038,
// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047,
// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056,
// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ]
//-> device_type_id = 0x0016
//-> certificate_id = "CSA00000SWC00000-00"
//-> security_level = 0
//-> security_information = 0
//-> version_number = 1
//-> certification_type = 0
//-> dac_origin_vendor_id is not present
//-> dac_origin_product_id is not present
constexpr const uint8_t kCdForAllExamples[540] = {
    0x30, 0x82, 0x02, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x08, 0x30, 0x82,
    0x02, 0x04, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30,
    0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x61, 0x04, 0x82, 0x01,
    0x5d, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05,
    0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05,
    0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05,
    0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05,
    0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05,
    0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05,
    0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05,
    0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05,
    0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05,
    0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05,
    0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05,
    0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05,
    0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05,
    0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05,
    0x5e, 0x80, 0x05, 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16,
    0x2c, 0x04, 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x53, 0x57, 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30,
    0x30, 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7c, 0x30, 0x7a, 0x02, 0x01, 0x03,
    0x80, 0x14, 0xfe, 0x34, 0x3f, 0x95, 0x99, 0x47, 0x76, 0x3b, 0x61, 0xee, 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4f, 0xe6, 0x7d,
    0x8e, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48,
    0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x4a, 0x12, 0xf8, 0xd4, 0x2f, 0x90, 0x23, 0x5c, 0x05, 0xa7,
    0x71, 0x21, 0xcb, 0xeb, 0xae, 0x15, 0xd5, 0x90, 0x14, 0x65, 0x58, 0xe9, 0xc9, 0xb4, 0x7a, 0x1a, 0x38, 0xf7, 0xa3, 0x6a, 0x7d,
    0xc5, 0x02, 0x20, 0x20, 0xa4, 0x74, 0x28, 0x97, 0xc3, 0x0a, 0xed, 0xa0, 0xa5, 0x6b, 0x36, 0xe1, 0x4e, 0xbb, 0xc8, 0x5b, 0xbd,
    0xb7, 0x44, 0x93, 0xf9, 0x93, 0x58, 0x1e, 0xb0, 0x44, 0x4e, 0xd6, 0xca, 0x94, 0x0b
};

namespace chip {
namespace Credentials {
namespace Examples {

namespace {

ByteSpan ReadValue(Json::Value jsonValue, uint8_t * buffer, size_t bufferLen)
{
    const std::string value = jsonValue.asString();
    if (value.size() == 0)
    {
        return ByteSpan();
    }

    size_t bytesLen = Encoding::HexToBytes(value.c_str(), value.size(), buffer, bufferLen);
    return ByteSpan(buffer, bytesLen);
}

CharSpan ReadValue(Json::Value jsonValue, char * buffer, size_t bufferLen)
{
    const std::string value = jsonValue.asString();
    if (value.size() == 0)
    {
        return CharSpan();
    }

    Platform::CopyString(buffer, bufferLen, value.c_str());
    return CharSpan(buffer, strlen(buffer));
}

bool ReadValue(Json::Value jsonValue)
{
    const std::string value = jsonValue.asString();
    if (strcmp(value.c_str(), "true") == 0)
    {
        return true;
    }
    return false;
}

// TODO: This should be moved to a method of P256Keypair
CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto::P256Keypair & keypair)
{
    Crypto::P256SerializedKeypair serialized_keypair;
    ReturnErrorOnFailure(serialized_keypair.SetLength(private_key.size() + public_key.size()));
    memcpy(serialized_keypair.Bytes(), public_key.data(), public_key.size());
    memcpy(serialized_keypair.Bytes() + public_key.size(), private_key.data(), private_key.size());
    return keypair.Deserialize(serialized_keypair);
}

} // namespace

TestHarnessDACProvider::TestHarnessDACProvider()
{
    TestHarnessDACProviderData data;
    Init(data);
}

void TestHarnessDACProvider::Init(const char * filepath)
{
    constexpr const char kDacCertKey[]      = "dac_cert";
    constexpr const char kDacPrivateKey[]   = "dac_private_key";
    constexpr const char kDacPublicKey[]    = "dac_public_key";
    constexpr const char kPaiCertKey[]      = "pai_cert";
    constexpr const char kCertDecKey[]      = "certification_declaration";
    constexpr const char kFirmwareInfoKey[] = "firmware_information";
    constexpr const char kIsSuccessKey[]    = "is_success_case";
    constexpr const char kDescription[]     = "description";

    std::ifstream json(filepath, std::ifstream::binary);
    if (!json)
    {
        ChipLogError(AppServer, "Error opening json file: %s", filepath);
        return;
    }

    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(json, root))
    {
        ChipLogError(AppServer, "Error parsing json file: %s", filepath);
        return;
    }

    TestHarnessDACProviderData data;

    if (root.isMember(kDacCertKey))
    {
        static uint8_t buf[kMaxDERCertLength];
        data.dacCert.SetValue(ReadValue(root[kDacCertKey], buf, sizeof(buf)));
    }

    if (root.isMember(kDacPrivateKey))
    {
        static uint8_t buf[Crypto::kP256_PrivateKey_Length];
        data.dacPrivateKey.SetValue(ReadValue(root[kDacPrivateKey], buf, sizeof(buf)));
    }

    if (root.isMember(kDacPublicKey))
    {
        static uint8_t buf[Crypto::kP256_PublicKey_Length];
        data.dacPublicKey.SetValue(ReadValue(root[kDacPublicKey], buf, sizeof(buf)));
    }

    if (root.isMember(kPaiCertKey))
    {
        static uint8_t buf[kMaxDERCertLength];
        data.paiCert.SetValue(ReadValue(root[kPaiCertKey], buf, sizeof(buf)));
    }

    if (root.isMember(kCertDecKey))
    {
        static uint8_t buf[kMaxCMSSignedCDMessage];
        data.certificationDeclaration.SetValue(ReadValue(root[kCertDecKey], buf, sizeof(buf)));
    }

    if (root.isMember(kFirmwareInfoKey))
    {
        // TODO Use the correct maximum size
        static uint8_t buf[UINT8_MAX];
        data.firmwareInformation.SetValue(ReadValue(root[kFirmwareInfoKey], buf, sizeof(buf)));
    }

    if (root.isMember(kIsSuccessKey))
    {
        data.isSuccessCase.SetValue(ReadValue(root[kIsSuccessKey]));
    }

    if (root.isMember(kDescription))
    {
        constexpr size_t kMaxTestCaseDescriptionLen = 256;
        static char buf[kMaxTestCaseDescriptionLen];
        data.description.SetValue(ReadValue(root[kDescription], buf, sizeof(buf)));
    }

    Init(data);
}

void TestHarnessDACProvider::Init(const TestHarnessDACProviderData & data)
{
    mDacCert       = data.dacCert.HasValue() ? data.dacCert.Value() : DevelopmentCerts::kDacCert;
    mDacPrivateKey = data.dacPrivateKey.HasValue() ? data.dacPrivateKey.Value() : DevelopmentCerts::kDacPrivateKey;
    mDacPublicKey  = data.dacPublicKey.HasValue() ? data.dacPublicKey.Value() : DevelopmentCerts::kDacPublicKey;
    mPaiCert       = data.paiCert.HasValue() ? data.paiCert.Value() : DevelopmentCerts::kPaiCert;
    mCertificationDeclaration =
        data.certificationDeclaration.HasValue() ? data.certificationDeclaration.Value() : ByteSpan{ kCdForAllExamples };
    mIsSuccessCase = data.isSuccessCase.HasValue() ? data.isSuccessCase.Value() : true;
    mDescription   = data.description.HasValue() ? data.description.Value() : CharSpan();

    // TODO: We need a real example FirmwareInformation to be populated.
    mFirmwareInformation = data.firmwareInformation.HasValue() ? data.firmwareInformation.Value() : ByteSpan();
}

CHIP_ERROR TestHarnessDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer)
{
    return CopySpanToMutableSpan(mDacCert, out_dac_buffer);
}

CHIP_ERROR TestHarnessDACProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer)
{
    return CopySpanToMutableSpan(mPaiCert, out_pai_buffer);
}

CHIP_ERROR TestHarnessDACProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer)
{
    return CopySpanToMutableSpan(mCertificationDeclaration, out_cd_buffer);
}

CHIP_ERROR TestHarnessDACProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer)
{
    return CopySpanToMutableSpan(mFirmwareInformation, out_firmware_info_buffer);
}

CHIP_ERROR TestHarnessDACProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign,
                                                                MutableByteSpan & out_signature_buffer)
{
    Crypto::P256ECDSASignature signature;
    Crypto::P256Keypair keypair;

    VerifyOrReturnError(IsSpanUsable(out_signature_buffer), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(out_signature_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL);

    // In a non-exemplary implementation, the public key is not needed here. It is used here merely because
    // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present.
    ReturnErrorOnFailure(LoadKeypairFromRaw(mDacPrivateKey, mDacPublicKey, keypair));
    ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature));

    return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_signature_buffer);
}

} // namespace Examples
} // namespace Credentials
} // namespace chip
