/*
 *   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.
 *
 */

#import <Matter/Matter.h>

#include "../common/CHIPCommandBridge.h"
#include "DeviceControllerDelegateBridge.h"
#include "PairingCommandBridge.h"
#include <lib/support/logging/CHIPLogging.h>

#import "MTRError_Utils.h"

using namespace ::chip;
using namespace ::chip::Controller;

void PairingCommandBridge::SetUpDeviceControllerDelegate()
{
    dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.pairing", DISPATCH_QUEUE_SERIAL);
    CHIPToolDeviceControllerDelegate * deviceControllerDelegate = [[CHIPToolDeviceControllerDelegate alloc] init];
    MTRCommissioningParameters * params = [[MTRCommissioningParameters alloc] init];
    MTRDeviceController * commissioner = CurrentCommissioner();

    [deviceControllerDelegate setDeviceID:mNodeId];
    switch (mNetworkType) {
    case PairingNetworkType::None:
    case PairingNetworkType::Ethernet:
        break;
    case PairingNetworkType::WiFi:
        [params setWifiSSID:[NSData dataWithBytes:mSSID.data() length:mSSID.size()]];
        [params setWifiCredentials:[NSData dataWithBytes:mPassword.data() length:mPassword.size()]];
        break;
    case PairingNetworkType::Thread:
        [params setThreadOperationalDataset:[NSData dataWithBytes:mOperationalDataset.data() length:mOperationalDataset.size()]];
        break;
    }

    [deviceControllerDelegate setCommandBridge:this];
    [deviceControllerDelegate setParams:params];
    [deviceControllerDelegate setCommissioner:commissioner];

    [commissioner setDeviceControllerDelegate:deviceControllerDelegate queue:callbackQueue];
}

CHIP_ERROR PairingCommandBridge::RunCommand()
{
    NSError * error;
    switch (mPairingMode) {
    case PairingMode::None:
        Unpair();
        break;
    case PairingMode::Code:
        PairWithPayload(&error);
        break;
    case PairingMode::Ble:
        PairWithCode(&error);
        break;
    }

    if (error != nil) {
        SetCommandExitStatus(error);
    }
    return CHIP_NO_ERROR;
}

void PairingCommandBridge::PairWithCode(NSError * __autoreleasing * error)
{
    SetUpDeviceControllerDelegate();
    auto * payload = [[MTRSetupPayload alloc] initWithSetupPasscode:@(mSetupPINCode) discriminator:@(mDiscriminator)];
    MTRDeviceController * commissioner = CurrentCommissioner();
    [commissioner setupCommissioningSessionWithPayload:payload newNodeID:@(mNodeId) error:error];
}

void PairingCommandBridge::PairWithPayload(NSError * __autoreleasing * error)
{
    NSString * onboardingPayload = [NSString stringWithUTF8String:mOnboardingPayload];
    SetUpDeviceControllerDelegate();
    auto * payload = [MTRSetupPayload setupPayloadWithOnboardingPayload:onboardingPayload error:error];
    if (payload == nil) {
        return;
    }
    MTRDeviceController * commissioner = CurrentCommissioner();
    [commissioner setupCommissioningSessionWithPayload:payload newNodeID:@(mNodeId) error:error];
}

void PairingCommandBridge::Unpair()
{
    dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip-tool.command", DISPATCH_QUEUE_SERIAL);
    MTRDeviceController * commissioner = CurrentCommissioner();
    auto * device = [MTRBaseDevice deviceWithNodeID:@(mNodeId) controller:commissioner];

    ChipLogProgress(chipTool, "Attempting to unpair device %llu", mNodeId);
    MTRBaseClusterOperationalCredentials * opCredsCluster =
        [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device endpoint:@(0) queue:callbackQueue];
    [opCredsCluster readAttributeCurrentFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable readError) {
        if (readError) {
            CHIP_ERROR readErr = MTRErrorToCHIPErrorCode(readError);
            LogNSError("Failed to get current fabric: ", readError);
            SetCommandExitStatus(readErr);
            return;
        }
        MTROperationalCredentialsClusterRemoveFabricParams * params =
            [[MTROperationalCredentialsClusterRemoveFabricParams alloc] init];
        params.fabricIndex = value;
        [opCredsCluster removeFabricWithParams:params
                                    completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                        NSError * _Nullable removeError) {
                                        CHIP_ERROR removeErr = CHIP_NO_ERROR;
                                        if (removeError) {
                                            removeErr = MTRErrorToCHIPErrorCode(removeError);
                                            LogNSError("Failed to remove current fabric: ", removeError);
                                        } else {
                                            ChipLogProgress(chipTool, "Successfully unpaired deviceId %llu", mNodeId);
                                        }
                                        SetCommandExitStatus(removeErr);
                                    }];
    }];
}
