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

#import "MTRDeviceControllerOverXPC_Internal.h"

#import "MTRDeviceController+XPC.h"
#import "MTRDeviceControllerXPCConnection.h"
#import "MTRDeviceOverXPC.h"
#import "MTRError.h"
#import "MTRLogging.h"

#import <Foundation/Foundation.h>

static dispatch_once_t workQueueInitOnceToken;
static dispatch_queue_t globalWorkQueue;

static void SetupXPCQueue(void)
{
    dispatch_once(&workQueueInitOnceToken, ^{
        globalWorkQueue = dispatch_queue_create("com.apple.matter.framework.xpc.workqueue", DISPATCH_QUEUE_SERIAL);
    });
}

@implementation MTRDeviceControllerOverXPC

+ (MTRDeviceControllerOverXPC *)sharedControllerWithId:(id<NSCopying> _Nullable)controllerId
                                       xpcConnectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
    SetupXPCQueue();
    return [[MTRDeviceControllerOverXPC alloc] initWithControllerId:controllerId
                                                          workQueue:globalWorkQueue
                                                       connectBlock:connectBlock];
}

- (BOOL)pairDevice:(uint64_t)deviceID
     discriminator:(uint16_t)discriminator
      setupPINCode:(uint32_t)setupPINCode
             error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
    return NO;
}

- (BOOL)pairDevice:(uint64_t)deviceID
           address:(NSString *)address
              port:(uint16_t)port
     discriminator:(uint16_t)discriminator
      setupPINCode:(uint32_t)setupPINCode
             error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
    return NO;
}

- (BOOL)pairDevice:(uint64_t)deviceID onboardingPayload:(NSString *)onboardingPayload error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
    return NO;
}

- (BOOL)commissionDevice:(uint64_t)deviceId
     commissioningParams:(MTRCommissioningParameters *)commissioningParams
                   error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
    return NO;
}

- (void)setListenPort:(uint16_t)port
{
    MTR_LOG_ERROR("MTRDevice doesn't support setListenPort over XPC");
}

- (BOOL)stopDevicePairing:(uint64_t)deviceID error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support stopDevicePairing over XPC");
    return NO;
}

- (nullable MTRBaseDevice *)getDeviceBeingCommissioned:(uint64_t)deviceId error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support getDeviceBeingCommissioned over XPC");
    return nil;
}

- (BOOL)getBaseDevice:(uint64_t)deviceID
                queue:(dispatch_queue_t)queue
    completionHandler:(MTRDeviceConnectionCallback)completionHandler
{
    dispatch_async(_workQueue, ^{
        dispatch_group_t group = dispatch_group_create();
        if (!self.controllerId) {
            dispatch_group_enter(group);
            [self.xpcConnection getProxyHandleWithCompletion:^(
                dispatch_queue_t _Nonnull queue, MTRDeviceControllerXPCProxyHandle * _Nullable handle) {
                if (handle) {
                    [handle.proxy getAnyDeviceControllerWithCompletion:^(id _Nullable controller, NSError * _Nullable error) {
                        if (error) {
                            MTR_LOG_ERROR("Failed to fetch any shared remote controller");
                        } else {
                            self.controllerId = controller;
                        }
                        dispatch_group_leave(group);
                        __auto_type handleRetainer = handle;
                        (void) handleRetainer;
                    }];
                } else {
                    MTR_LOG_ERROR("XPC disconnected while retrieving any shared remote controller");
                    dispatch_group_leave(group);
                }
            }];
        }
        dispatch_group_notify(group, queue, ^{
            if (self.controllerId) {
                MTRDeviceOverXPC * device = [[MTRDeviceOverXPC alloc] initWithController:self.controllerId
                                                                                deviceId:deviceID
                                                                           xpcConnection:self.xpcConnection];
                completionHandler(device, nil);
            } else {
                completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
            }
        });
    });
    return YES;
}

- (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support openPairingWindow over XPC");
    return NO;
}

- (nullable NSString *)openPairingWindowWithPIN:(uint64_t)deviceID
                                       duration:(NSUInteger)duration
                                  discriminator:(NSUInteger)discriminator
                                       setupPIN:(NSUInteger)setupPIN
                                          error:(NSError * __autoreleasing *)error
{
    MTR_LOG_ERROR("MTRDevice doesn't support openPairingWindow over XPC");
    return nil;
}

- (instancetype)initWithControllerId:(id)controllerId
                           workQueue:(dispatch_queue_t)queue
                       xpcConnection:(MTRDeviceControllerXPCConnection *)connection
{
    _controllerId = controllerId;
    _workQueue = queue;
    _xpcConnection = connection;
    return self;
}

// This is interface for unit testing
- (instancetype)initWithControllerId:(id)controllerId
                           workQueue:(dispatch_queue_t)queue
                        connectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
    return [self initWithControllerId:controllerId
                            workQueue:queue
                        xpcConnection:[MTRDeviceControllerXPCConnection connectionWithWorkQueue:queue connectBlock:connectBlock]];
}

@end
