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

#import "MTRCertificates.h"
#import "MTRError_Internal.h"
#import "MTRFramework.h"
#import "MTRLogging_Internal.h"
#import "MTROperationalCredentialsDelegate.h"
#import "MTRP256KeypairBridge.h"
#import "NSDataSpanConversion.h"

#include <credentials/CHIPCert.h>
#include <crypto/CHIPCryptoPAL.h>

using namespace chip;
using namespace chip::Crypto;
using namespace chip::Credentials;

@implementation MTRCertificates

+ (void)initialize
{
    MTRFrameworkInit();
}

+ (MTRCertificateDERBytes _Nullable)createRootCertificate:(id<MTRKeypair>)keypair
                                                 issuerID:(NSNumber * _Nullable)issuerID
                                                 fabricID:(NSNumber * _Nullable)fabricID
                                           validityPeriod:(NSDateInterval *)validityPeriod
                                                    error:(NSError * __autoreleasing *)error
{
    MTR_LOG_DEFAULT("Generating root certificate");
    NSData * rootCert = nil;
    CHIP_ERROR err
        = MTROperationalCredentialsDelegate::GenerateRootCertificate(keypair, issuerID, fabricID, validityPeriod, &rootCert);
    if (error) {
        *error = [MTRError errorForCHIPErrorCode:err];
    }

    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Generating root certificate failed: %s", ErrorStr(err));
    }

    return rootCert;
}

+ (MTRCertificateDERBytes _Nullable)createRootCertificate:(id<MTRKeypair>)keypair
                                                 issuerID:(NSNumber * _Nullable)issuerID
                                                 fabricID:(NSNumber * _Nullable)fabricID
                                                    error:(NSError * __autoreleasing *)error
{
    auto * validityPeriod = [[NSDateInterval alloc] initWithStartDate:[NSDate now] endDate:[NSDate distantFuture]];
    return [self createRootCertificate:keypair issuerID:issuerID fabricID:fabricID validityPeriod:validityPeriod error:error];
}

+ (MTRCertificateDERBytes _Nullable)createIntermediateCertificate:(id<MTRKeypair>)rootKeypair
                                                  rootCertificate:(MTRCertificateDERBytes)rootCertificate
                                            intermediatePublicKey:(SecKeyRef)intermediatePublicKey
                                                         issuerID:(NSNumber * _Nullable)issuerID
                                                         fabricID:(NSNumber * _Nullable)fabricID
                                                   validityPeriod:(NSDateInterval *)validityPeriod
                                                            error:(NSError * __autoreleasing *)error
{
    MTR_LOG_DEFAULT("Generating intermediate certificate");
    NSData * intermediate = nil;
    CHIP_ERROR err = MTROperationalCredentialsDelegate::GenerateIntermediateCertificate(
        rootKeypair, rootCertificate, intermediatePublicKey, issuerID, fabricID, validityPeriod, &intermediate);
    if (error) {
        *error = [MTRError errorForCHIPErrorCode:err];
    }

    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Generating intermediate certificate failed: %s", ErrorStr(err));
    }

    return intermediate;
}

+ (MTRCertificateDERBytes _Nullable)createIntermediateCertificate:(id<MTRKeypair>)rootKeypair
                                                  rootCertificate:(MTRCertificateDERBytes)rootCertificate
                                            intermediatePublicKey:(SecKeyRef)intermediatePublicKey
                                                         issuerID:(NSNumber * _Nullable)issuerID
                                                         fabricID:(NSNumber * _Nullable)fabricID
                                                            error:(NSError * __autoreleasing *)error
{
    auto * validityPeriod = [[NSDateInterval alloc] initWithStartDate:[NSDate now] endDate:[NSDate distantFuture]];
    return [self createIntermediateCertificate:rootKeypair
                               rootCertificate:rootCertificate
                         intermediatePublicKey:intermediatePublicKey
                                      issuerID:issuerID
                                      fabricID:fabricID
                                validityPeriod:validityPeriod
                                         error:error];
}

+ (MTRCertificateDERBytes _Nullable)createOperationalCertificate:(id<MTRKeypair>)signingKeypair
                                              signingCertificate:(MTRCertificateDERBytes)signingCertificate
                                            operationalPublicKey:(SecKeyRef)operationalPublicKey
                                                        fabricID:(NSNumber *)fabricID
                                                          nodeID:(NSNumber *)nodeID
                                           caseAuthenticatedTags:(NSSet<NSNumber *> * _Nullable)caseAuthenticatedTags
                                                  validityPeriod:(NSDateInterval *)validityPeriod
                                                           error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    MTR_LOG_DEFAULT("Generating operational certificate");
    NSData * opcert = nil;
    CHIP_ERROR err = MTROperationalCredentialsDelegate::GenerateOperationalCertificate(
        signingKeypair, signingCertificate, operationalPublicKey, fabricID, nodeID, caseAuthenticatedTags, validityPeriod, &opcert);
    if (error) {
        *error = [MTRError errorForCHIPErrorCode:err];
    }

    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Generating operational certificate failed: %s", ErrorStr(err));
    }

    return opcert;
}

+ (MTRCertificateDERBytes _Nullable)createOperationalCertificate:(id<MTRKeypair>)signingKeypair
                                              signingCertificate:(MTRCertificateDERBytes)signingCertificate
                                            operationalPublicKey:(SecKeyRef)operationalPublicKey
                                                        fabricID:(NSNumber *)fabricID
                                                          nodeID:(NSNumber *)nodeID
                                           caseAuthenticatedTags:(NSSet<NSNumber *> * _Nullable)caseAuthenticatedTags
                                                           error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    auto * validityPeriod = [[NSDateInterval alloc] initWithStartDate:[NSDate now] endDate:[NSDate distantFuture]];
    return [self createOperationalCertificate:signingKeypair
                           signingCertificate:signingCertificate
                         operationalPublicKey:operationalPublicKey
                                     fabricID:fabricID
                                       nodeID:nodeID
                        caseAuthenticatedTags:caseAuthenticatedTags
                               validityPeriod:validityPeriod
                                        error:error];
}

+ (BOOL)keypair:(id<MTRKeypair>)keypair matchesCertificate:(NSData *)certificate
{
    P256PublicKey keypairPubKey;
    CHIP_ERROR err = MTRP256KeypairBridge::MatterPubKeyFromSecKeyRef(keypair.publicKey, &keypairPubKey);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract public key from keypair: %s", ErrorStr(err));
        return NO;
    }
    P256PublicKeySpan keypairKeySpan(keypairPubKey.ConstBytes());

    P256PublicKey certPubKey;
    err = ExtractPubkeyFromX509Cert(AsByteSpan(certificate), certPubKey);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract public key from certificate: %s", ErrorStr(err));
        return NO;
    }
    P256PublicKeySpan certKeySpan(certPubKey.ConstBytes());

    return certKeySpan.data_equal(keypairKeySpan);
}

+ (BOOL)isCertificate:(MTRCertificateDERBytes)certificate1 equalTo:(MTRCertificateDERBytes)certificate2
{
    P256PublicKey pubKey1;
    CHIP_ERROR err = ExtractPubkeyFromX509Cert(AsByteSpan(certificate1), pubKey1);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract public key from first certificate: %s", ErrorStr(err));
        return NO;
    }
    P256PublicKeySpan keySpan1(pubKey1.ConstBytes());

    P256PublicKey pubKey2;
    err = ExtractPubkeyFromX509Cert(AsByteSpan(certificate2), pubKey2);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract public key from second certificate: %s", ErrorStr(err));
        return NO;
    }
    P256PublicKeySpan keySpan2(pubKey1.ConstBytes());

    if (!keySpan1.data_equal(keySpan2)) {
        return NO;
    }

    ChipDN subject1;
    err = ExtractSubjectDNFromX509Cert(AsByteSpan(certificate1), subject1);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract subject DN from first certificate: %s", ErrorStr(err));
        return NO;
    }

    ChipDN subject2;
    err = ExtractSubjectDNFromX509Cert(AsByteSpan(certificate2), subject2);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("Can't extract subject DN from second certificate: %s", ErrorStr(err));
        return NO;
    }

    return subject1.IsEqual(subject2);
}

+ (NSData * _Nullable)createCertificateSigningRequest:(id<MTRKeypair>)keypair
                                                error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    MTRP256KeypairBridge keypairBridge;
    CHIP_ERROR err = CHIP_NO_ERROR;
    do {
        err = keypairBridge.Init(keypair);
        if (err != CHIP_NO_ERROR) {
            break;
        }

        uint8_t buf[kMAX_CSR_Length];
        MutableByteSpan csr(buf);
        err = GenerateCertificateSigningRequest(&keypairBridge, csr);
        if (err != CHIP_NO_ERROR) {
            break;
        }

        return AsData(csr);
    } while (0);

    if (error) {
        *error = [MTRError errorForCHIPErrorCode:err];
    }
    return nil;
}

+ (MTRCertificateTLVBytes _Nullable)convertX509Certificate:(MTRCertificateDERBytes)x509Certificate
{

    chip::ByteSpan x509CertBytes = AsByteSpan(x509Certificate);

    uint8_t chipCertBuffer[chip::Credentials::kMaxCHIPCertLength];
    chip::MutableByteSpan chipCertBytes(chipCertBuffer);

    CHIP_ERROR errorCode = chip::Credentials::ConvertX509CertToChipCert(x509CertBytes, chipCertBytes);
    if (errorCode != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("convertX509Certificate: %s", errorCode.AsString());
        return nil;
    }

    MTR_LOG_INFO("convertX509Certificate: Success");

    return AsData(chipCertBytes);
}

+ (MTRCertificateDERBytes _Nullable)convertMatterCertificate:(MTRCertificateTLVBytes)matterCertificate
{
    chip::ByteSpan tlvCertBytes = AsByteSpan(matterCertificate);

    uint8_t derCertBuffer[chip::Controller::kMaxCHIPDERCertLength];
    chip::MutableByteSpan derCertBytes(derCertBuffer);

    CHIP_ERROR errorCode = chip::Credentials::ConvertChipCertToX509Cert(tlvCertBytes, derCertBytes);

    if (errorCode != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("convertMatterCertificate: %s", chip::ErrorStr(errorCode));
        return nil;
    }

    return AsData(derCertBytes);
}

+ (NSData * _Nullable)publicKeyFromCSR:(MTRCSRDERBytes)certificateSigningRequest
                                 error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    auto requestSpan = AsByteSpan(certificateSigningRequest);
    P256PublicKey publicKey;
    CHIP_ERROR err = VerifyCertificateSigningRequest(requestSpan.data(), requestSpan.size(), publicKey);
    if (err != CHIP_NO_ERROR) {
        MTR_LOG_ERROR("publicKeyFromCSR: %s", chip::ErrorStr(err));
        if (error) {
            *error = [MTRError errorForCHIPErrorCode:err];
        }
        return nil;
    }

    P256PublicKeySpan publicKeySpan(publicKey.ConstBytes());
    return AsData(publicKeySpan);
}

@end

@implementation MTRCertificates (Deprecated)

+ (nullable NSData *)generateRootCertificate:(id<MTRKeypair>)keypair
                                    issuerId:(nullable NSNumber *)issuerId
                                    fabricId:(nullable NSNumber *)fabricId
                                       error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    return [MTRCertificates createRootCertificate:keypair issuerID:issuerId fabricID:fabricId error:error];
}

+ (nullable NSData *)generateIntermediateCertificate:(id<MTRKeypair>)rootKeypair
                                     rootCertificate:(NSData *)rootCertificate
                               intermediatePublicKey:(SecKeyRef)intermediatePublicKey
                                            issuerId:(nullable NSNumber *)issuerId
                                            fabricId:(nullable NSNumber *)fabricId
                                               error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    return [MTRCertificates createIntermediateCertificate:rootKeypair
                                          rootCertificate:rootCertificate
                                    intermediatePublicKey:intermediatePublicKey
                                                 issuerID:issuerId
                                                 fabricID:fabricId
                                                    error:error];
}

+ (nullable NSData *)generateOperationalCertificate:(id<MTRKeypair>)signingKeypair
                                 signingCertificate:(NSData *)signingCertificate
                               operationalPublicKey:(SecKeyRef)operationalPublicKey
                                           fabricId:(NSNumber *)fabricId
                                             nodeId:(NSNumber *)nodeId
                              caseAuthenticatedTags:(NSArray<NSNumber *> * _Nullable)caseAuthenticatedTags
                                              error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    NSSet<NSNumber *> * tags = nil;
    if (caseAuthenticatedTags != nil) {
        tags = [NSSet setWithArray:caseAuthenticatedTags];
    }
    return [MTRCertificates createOperationalCertificate:signingKeypair
                                      signingCertificate:signingCertificate
                                    operationalPublicKey:operationalPublicKey
                                                fabricID:fabricId
                                                  nodeID:nodeId
                                   caseAuthenticatedTags:tags
                                                   error:error];
}

+ (nullable NSData *)generateCertificateSigningRequest:(id<MTRKeypair>)keypair
                                                 error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
    return [MTRCertificates createCertificateSigningRequest:keypair error:error];
}

@end
