/**
 *
 *    Copyright (c) 2020-2024 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 "MTRSetupPayload_Internal.h"

#import "MTRError_Internal.h"
#import "MTRFramework.h"
#import "MTROnboardingPayloadParser.h"

#include <setup_payload/ManualSetupPayloadGenerator.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>
#include <string>

@implementation MTROptionalQRCodeInfo
@end

MTR_DIRECT_MEMBERS
@implementation MTRSetupPayload {
    chip::SetupPayload _chipSetupPayload;
}

+ (void)initialize
{
    // Need to make sure we set up Platform memory stuff before we start
    // serializing payloads.
    MTRFrameworkInit();
}

- (MTRDiscoveryCapabilities)convertRendezvousFlags:(const chip::Optional<chip::RendezvousInformationFlags> &)value
{
    if (!value.HasValue()) {
        return MTRDiscoveryCapabilitiesUnknown;
    }

    NSUInteger flags = 0;
    if (value.Value().Has(chip::RendezvousInformationFlag::kBLE)) {
        flags |= MTRDiscoveryCapabilitiesBLE;
    }
    if (value.Value().Has(chip::RendezvousInformationFlag::kSoftAP)) {
        flags |= MTRDiscoveryCapabilitiesSoftAP;
    }
    if (value.Value().Has(chip::RendezvousInformationFlag::kOnNetwork)) {
        flags |= MTRDiscoveryCapabilitiesOnNetwork;
    }
    if (flags == MTRDiscoveryCapabilitiesUnknown) {
        // OnNetwork has to be supported!
        flags = MTRDiscoveryCapabilitiesOnNetwork;
    }
    return flags;
}

+ (chip::Optional<chip::RendezvousInformationFlags>)convertDiscoveryCapabilities:(MTRDiscoveryCapabilities)value
{
    if (value == MTRDiscoveryCapabilitiesUnknown) {
        return chip::NullOptional;
    }

    chip::RendezvousInformationFlags flags;
    if (value & MTRDiscoveryCapabilitiesBLE) {
        flags.Set(chip::RendezvousInformationFlag::kBLE);
    }
    if (value & MTRDiscoveryCapabilitiesSoftAP) {
        flags.Set(chip::RendezvousInformationFlag::kSoftAP);
    }
    if (value & MTRDiscoveryCapabilitiesOnNetwork) {
        flags.Set(chip::RendezvousInformationFlag::kOnNetwork);
    }
    return chip::MakeOptional(flags);
}

- (MTRCommissioningFlow)convertCommissioningFlow:(chip::CommissioningFlow)value
{
    if (value == chip::CommissioningFlow::kStandard) {
        return MTRCommissioningFlowStandard;
    }
    if (value == chip::CommissioningFlow::kUserActionRequired) {
        return MTRCommissioningFlowUserActionRequired;
    }
    if (value == chip::CommissioningFlow::kCustom) {
        return MTRCommissioningFlowCustom;
    }
    return MTRCommissioningFlowInvalid;
}

+ (chip::CommissioningFlow)unconvertCommissioningFlow:(MTRCommissioningFlow)value
{
    if (value == MTRCommissioningFlowStandard) {
        return chip::CommissioningFlow::kStandard;
    }
    if (value == MTRCommissioningFlowUserActionRequired) {
        return chip::CommissioningFlow::kUserActionRequired;
    }
    if (value == MTRCommissioningFlowCustom) {
        return chip::CommissioningFlow::kCustom;
    }
    // It's MTRCommissioningFlowInvalid ... now what?  But in practice
    // this is not called when we have MTRCommissioningFlowInvalid.
    return chip::CommissioningFlow::kStandard;
}

- (instancetype)initWithSetupPayload:(chip::SetupPayload)setupPayload
{
    if (self = [super init]) {
        _chipSetupPayload = setupPayload;
        _version = [NSNumber numberWithUnsignedChar:setupPayload.version];
        _vendorID = [NSNumber numberWithUnsignedShort:setupPayload.vendorID];
        _productID = [NSNumber numberWithUnsignedShort:setupPayload.productID];
        _commissioningFlow = [self convertCommissioningFlow:setupPayload.commissioningFlow];
        _discoveryCapabilities = [self convertRendezvousFlags:setupPayload.rendezvousInformation];
        _hasShortDiscriminator = setupPayload.discriminator.IsShortDiscriminator();
        if (_hasShortDiscriminator) {
            _discriminator = [NSNumber numberWithUnsignedShort:setupPayload.discriminator.GetShortValue()];
        } else {
            _discriminator = [NSNumber numberWithUnsignedShort:setupPayload.discriminator.GetLongValue()];
        }
        _setupPasscode = [NSNumber numberWithUnsignedInt:setupPayload.setUpPINCode];

        [self getSerialNumber:setupPayload];
    }
    return self;
}

- (instancetype)initWithSetupPasscode:(NSNumber *)setupPasscode discriminator:(NSNumber *)discriminator
{
    if (self = [super init]) {
        _version = @(0); // Only supported Matter version so far.
        _vendorID = @(0); // Not available.
        _productID = @(0); // Not available.
        _commissioningFlow = MTRCommissioningFlowStandard;
        // We are using a long discriminator, so have to have a known
        // discoveryCapabilities to be a valid payload.  Just default to "try
        // all discovery methods".
        _discoveryCapabilities = MTRDiscoveryCapabilitiesAllMask;
        _hasShortDiscriminator = NO;
        _discriminator = discriminator;
        _setupPasscode = setupPasscode;
        _serialNumber = nil;
    }
    return self;
}

- (void)getSerialNumber:(chip::SetupPayload)setupPayload
{
    std::string serialNumberC;
    CHIP_ERROR err = setupPayload.getSerialNumber(serialNumberC);
    if (err == CHIP_NO_ERROR) {
        _serialNumber = [NSString stringWithUTF8String:serialNumberC.c_str()];
    }
}

- (NSArray<MTROptionalQRCodeInfo *> *)getAllOptionalVendorData:(NSError * __autoreleasing *)error
{
    NSMutableArray<MTROptionalQRCodeInfo *> * allOptionalData = [NSMutableArray new];
    std::vector<chip::OptionalQRCodeInfo> chipOptionalData = _chipSetupPayload.getAllOptionalVendorData();
    for (chip::OptionalQRCodeInfo chipInfo : chipOptionalData) {
        MTROptionalQRCodeInfo * info = [MTROptionalQRCodeInfo new];
        info.tag = [NSNumber numberWithUnsignedChar:chipInfo.tag];
        switch (chipInfo.type) {
        case chip::optionalQRCodeInfoTypeString:
            info.type = MTROptionalQRCodeInfoTypeString;
            info.stringValue = [NSString stringWithUTF8String:chipInfo.data.c_str()];
            break;
        case chip::optionalQRCodeInfoTypeInt32:
            info.type = MTROptionalQRCodeInfoTypeInt32;
            info.integerValue = [NSNumber numberWithInt:chipInfo.int32];
            break;
        default:
            if (error) {
                *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeInvalidArgument userInfo:nil];
            }
            return nil;
        }
        [allOptionalData addObject:info];
    }
    return allOptionalData;
}

+ (NSUInteger)generateRandomPIN
{
    return [[MTRSetupPayload generateRandomSetupPasscode] unsignedIntValue];
}

+ (NSNumber *)generateRandomSetupPasscode
{
    do {
        // Make sure the thing we generate is in the right range.
        uint32_t setupPIN = arc4random_uniform(chip::kSetupPINCodeMaximumValue) + 1;
        if (chip::SetupPayload::IsValidSetupPIN(setupPIN)) {
            return @(setupPIN);
        }

        // We got pretty unlikely with our random number generation.  Just try
        // again.  The chance that this loop does not terminate in a reasonable
        // amount of time is astronomically low, assuming arc4random_uniform is not
        // broken.
    } while (true);

    // Not reached.
    return @(chip::kSetupPINCodeUndefinedValue);
}

+ (bool)isQRCode:(NSString *)onboardingPayload
{
    return [onboardingPayload hasPrefix:@"MT:"];
}

+ (MTRSetupPayload * _Nullable)setupPayloadWithOnboardingPayload:(NSString *)onboardingPayload
                                                           error:(NSError * __autoreleasing *)error
{
    // TODO: Do we actually need the MTROnboardingPayloadParser abstraction?
    MTRSetupPayload * payload = [MTROnboardingPayloadParser setupPayloadForOnboardingPayload:onboardingPayload error:error];
    if (payload == nil) {
        return nil;
    }

    bool isQRCode = [MTRSetupPayload isQRCode:onboardingPayload];
    bool validPayload;
    if (isQRCode) {
        validPayload = payload->_chipSetupPayload.isValidQRCodePayload();
    } else {
        validPayload = payload->_chipSetupPayload.isValidManualCode();
    }

    if (!validPayload) {
        if (error) {
            *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT logContext:onboardingPayload];
        }
        return nil;
    }

    return payload;
}

- (NSString *)description
{
    NSMutableArray<NSString *> * capabilities = [NSMutableArray array];
    if (self.discoveryCapabilities & MTRDiscoveryCapabilitiesSoftAP) {
        [capabilities addObject:@"SoftAP"];
    }
    if (self.discoveryCapabilities & MTRDiscoveryCapabilitiesBLE) {
        [capabilities addObject:@"BLE"];
    }
    if (self.discoveryCapabilities & MTRDiscoveryCapabilitiesOnNetwork) {
        [capabilities addObject:@"OnNetwork"];
    }
    if (capabilities.count == 0) {
        [capabilities addObject:@"Unknown"];
    }

    return [NSString stringWithFormat:@"<MTRSetupPayload: discriminator=0x%x hasShortDiscriminator=%@ discoveryCapabilities=%@>",
                     self.discriminator.unsignedIntValue, self.hasShortDiscriminator ? @"YES" : @"NO", [capabilities componentsJoinedByString:@"|"]];
}

#pragma mark - NSSecureCoding

static NSString * const MTRSetupPayloadCodingKeyVersion = @"MTRSP.ck.version";
static NSString * const MTRSetupPayloadCodingKeyVendorID = @"MTRSP.ck.vendorID";
static NSString * const MTRSetupPayloadCodingKeyProductID = @"MTRSP.ck.productID";
static NSString * const MTRSetupPayloadCodingKeyCommissioningFlow = @"MTRSP.ck.commissioningFlow";
static NSString * const MTRSetupPayloadCodingKeyDiscoveryCapabilities = @"MTRSP.ck.rendezvousFlags";
static NSString * const MTRSetupPayloadCodingKeyHasShortDiscriminator = @"MTRSP.ck.hasShortDiscriminator";
static NSString * const MTRSetupPayloadCodingKeyDiscriminator = @"MTRSP.ck.discriminator";
static NSString * const MTRSetupPayloadCodingKeySetupPasscode = @"MTRSP.ck.setupPINCode";
static NSString * const MTRSetupPayloadCodingKeySerialNumber = @"MTRSP.ck.serialNumber";

+ (BOOL)supportsSecureCoding
{
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:self.version forKey:MTRSetupPayloadCodingKeyVersion];
    [coder encodeObject:self.vendorID forKey:MTRSetupPayloadCodingKeyVendorID];
    [coder encodeObject:self.productID forKey:MTRSetupPayloadCodingKeyProductID];
    // Casts are safe because commissioning flow, discoveryCapabilities, and
    // hasShortDiscriminator values are all pretty small and non-negative.
    [coder encodeInteger:static_cast<NSInteger>(self.commissioningFlow) forKey:MTRSetupPayloadCodingKeyCommissioningFlow];
    // We used to encode the discovery capabilities as an NSNumber object, with
    // nil representing "unknown".  Keep doing that, for backwards compat.
    [coder encodeObject:[MTRSetupPayload _boxDiscoveryCapabilities:self.discoveryCapabilities]
                 forKey:MTRSetupPayloadCodingKeyDiscoveryCapabilities];
    [coder encodeInteger:static_cast<NSInteger>(self.hasShortDiscriminator) forKey:MTRSetupPayloadCodingKeyHasShortDiscriminator];
    [coder encodeObject:self.discriminator forKey:MTRSetupPayloadCodingKeyDiscriminator];
    [coder encodeObject:self.setupPasscode forKey:MTRSetupPayloadCodingKeySetupPasscode];
    [coder encodeObject:self.serialNumber forKey:MTRSetupPayloadCodingKeySerialNumber];
}

- (instancetype _Nullable)initWithCoder:(NSCoder *)decoder
{
    NSNumber * version = [decoder decodeObjectOfClass:[NSNumber class] forKey:MTRSetupPayloadCodingKeyVersion];
    NSNumber * vendorID = [decoder decodeObjectOfClass:[NSNumber class] forKey:MTRSetupPayloadCodingKeyVendorID];
    NSNumber * productID = [decoder decodeObjectOfClass:[NSNumber class] forKey:MTRSetupPayloadCodingKeyProductID];
    NSInteger commissioningFlow = [decoder decodeIntegerForKey:MTRSetupPayloadCodingKeyCommissioningFlow];
    MTRDiscoveryCapabilities discoveryCapabilities =
        [MTRSetupPayload _unboxDiscoveryCapabilities:[decoder decodeObjectOfClass:[NSNumber class]
                                                                           forKey:MTRSetupPayloadCodingKeyDiscoveryCapabilities]];
    NSInteger hasShortDiscriminator = [decoder decodeIntegerForKey:MTRSetupPayloadCodingKeyHasShortDiscriminator];
    NSNumber * discriminator = [decoder decodeObjectOfClass:[NSNumber class] forKey:MTRSetupPayloadCodingKeyDiscriminator];
    NSNumber * setupPasscode = [decoder decodeObjectOfClass:[NSNumber class] forKey:MTRSetupPayloadCodingKeySetupPasscode];
    NSString * serialNumber = [decoder decodeObjectOfClass:[NSString class] forKey:MTRSetupPayloadCodingKeySerialNumber];

    MTRSetupPayload * payload = [[MTRSetupPayload alloc] init];
    payload.version = version;
    payload.vendorID = vendorID;
    payload.productID = productID;
    payload.commissioningFlow = static_cast<MTRCommissioningFlow>(commissioningFlow);
    payload.discoveryCapabilities = discoveryCapabilities;
    payload.hasShortDiscriminator = static_cast<BOOL>(hasShortDiscriminator);
    payload.discriminator = discriminator;
    payload.setupPasscode = setupPasscode;
    payload.serialNumber = serialNumber;

    return payload;
}

- (NSString * _Nullable)manualEntryCode
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    std::string outDecimalString;
    chip::SetupPayload payload;

    /// The 11 digit manual pairing code only requires the version, VID_PID present flag,
    /// discriminator, and the setup pincode.
    payload.version = [self.version unsignedCharValue];
    if (self.hasShortDiscriminator) {
        payload.discriminator.SetShortValue([self.discriminator unsignedCharValue]);
    } else {
        payload.discriminator.SetLongValue([self.discriminator unsignedShortValue]);
    }
    payload.setUpPINCode = [self.setupPasscode unsignedIntValue];

    err = chip::ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(outDecimalString);

    if (err != CHIP_NO_ERROR) {
        return nil;
    }

    return [NSString stringWithUTF8String:outDecimalString.c_str()];
}

- (NSString * _Nullable)qrCodeString:(NSError * __autoreleasing *)error
{
    if (self.commissioningFlow == MTRCommissioningFlowInvalid) {
        // No idea how to map this to the standard codes.
        if (error != nil) {
            *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE logContext:@"invalid flow"];
        }
        return nil;
    }

    if (self.hasShortDiscriminator) {
        // Can't create a QR code with a short discriminator.
        if (error != nil) {
            *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE logContext:@"cannot create a QR code with a short descrimintor"];
        }
        return nil;
    }

    if (self.discoveryCapabilities == MTRDiscoveryCapabilitiesUnknown) {
        // Can't create a QR code if we don't know the discovery capabilities.
        if (error != nil) {
            *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE logContext:@"cannot create a QR code with unknown discovery capabilities"];
        }
        return nil;
    }

    chip::SetupPayload payload;

    payload.version = [self.version unsignedCharValue];
    payload.vendorID = [self.vendorID unsignedShortValue];
    payload.productID = [self.productID unsignedShortValue];
    payload.commissioningFlow = [MTRSetupPayload unconvertCommissioningFlow:self.commissioningFlow];
    payload.rendezvousInformation = [MTRSetupPayload convertDiscoveryCapabilities:self.discoveryCapabilities];
    payload.discriminator.SetLongValue([self.discriminator unsignedShortValue]);
    payload.setUpPINCode = [self.setupPasscode unsignedIntValue];
    if (self.serialNumber != nil) {
        CHIP_ERROR err = payload.addSerialNumber(self.serialNumber.UTF8String);
        if (err != CHIP_NO_ERROR) {
            if (error != nil) {
                *error = [MTRError errorForCHIPErrorCode:err];
            }
            return nil;
        }
    }

    std::string outQRCodeString;
    CHIP_ERROR err = chip::QRCodeSetupPayloadGenerator(payload).payloadBase38RepresentationWithAutoTLVBuffer(outQRCodeString);

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

    return [NSString stringWithUTF8String:outQRCodeString.c_str()];
}

+ (nullable NSNumber *)_boxDiscoveryCapabilities:(MTRDiscoveryCapabilities)discoveryCapabilities
{
    if (discoveryCapabilities == MTRDiscoveryCapabilitiesUnknown) {
        return nil;
    }

    return @(discoveryCapabilities);
}

+ (MTRDiscoveryCapabilities)_unboxDiscoveryCapabilities:(nullable NSNumber *)boxedDiscoveryCapabilities
{
    if (boxedDiscoveryCapabilities == nil) {
        return MTRDiscoveryCapabilitiesUnknown;
    }

    NSUInteger value = [boxedDiscoveryCapabilities unsignedIntegerValue];
    if (value == MTRDiscoveryCapabilitiesUnknown) {
        // The discovery capabilities were actually known
        // (rendezvousInformation is not nil), and must support on-network.
        return MTRDiscoveryCapabilitiesOnNetwork;
    }

    return static_cast<MTRDiscoveryCapabilities>(value);
}

@end

MTR_DIRECT_MEMBERS
@implementation MTROptionalQRCodeInfo (Deprecated)

- (NSNumber *)infoType
{
    return @(self.type);
}

- (void)setInfoType:(NSNumber *)infoType
{
    self.type = static_cast<MTROptionalQRCodeInfoType>([infoType unsignedIntegerValue]);
}

@end

MTR_DIRECT_MEMBERS
@implementation MTRSetupPayload (Deprecated)

- (nullable NSNumber *)rendezvousInformation
{
    return [MTRSetupPayload _boxDiscoveryCapabilities:self.discoveryCapabilities];
}

- (void)setRendezvousInformation:(nullable NSNumber *)rendezvousInformation
{
    self.discoveryCapabilities = [MTRSetupPayload _unboxDiscoveryCapabilities:rendezvousInformation];
}

- (NSNumber *)setUpPINCode
{
    return self.setupPasscode;
}

- (void)setSetUpPINCode:(NSNumber *)setUpPINCode
{
    self.setupPasscode = setUpPINCode;
}

- (instancetype)init
{
    if (self = [super init]) {
        _version = @(0); // Only supported Matter version so far.
        _vendorID = @(0); // Not available.
        _productID = @(0); // Not available.
        _commissioningFlow = MTRCommissioningFlowStandard;
        _discoveryCapabilities = MTRDiscoveryCapabilitiesUnknown;
        _hasShortDiscriminator = NO;
        _discriminator = @(0);
        _setupPasscode = @(11111111); // Invalid passcode
        _serialNumber = nil;
    }

    return self;
}

+ (instancetype)new
{
    return [[self alloc] init];
}

@end
