/*
 *
 *    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", StringOrNullMarker(filepath));
        return;
    }

    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(json, root))
    {
        ChipLogError(AppServer, "Error parsing json file: %s", StringOrNullMarker(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
