/**
 *
 *    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 "MTRDeviceControllerXPCConnection.h"
#import "MTRDeviceControllerOverXPC.h"
#import "MTRLogging_Internal.h"

#import <Foundation/Foundation.h>

@interface MTRDeviceControllerXPCProxyHandle ()
@property (weak, nonatomic, readonly) NSXPCConnection * xpcConnection;

- (instancetype)initWithXPCConnection:(NSXPCConnection *)xpcConnection;

@end

@implementation MTRDeviceControllerXPCProxyHandle

- (instancetype)initWithXPCConnection:(NSXPCConnection *)xpcConnection
{
    if ([super init]) {
        _xpcConnection = xpcConnection;
    }
    return self;
}

- (id<MTRDeviceControllerServerProtocol>)proxy
{
    return [_xpcConnection remoteObjectProxy];
}

- (void)dealloc
{
    [_xpcConnection invalidate];
}

@end

@interface MTRDeviceControllerXPCConnection ()

@property (strong, nonatomic, readonly) NSXPCInterface * remoteDeviceServerProtocol;
@property (strong, nonatomic, readonly) NSXPCInterface * remoteDeviceClientProtocol;
@property (strong, nonatomic, readonly) NSXPCConnection * (^connectBlock)(void);
@property (weak, nonatomic, readwrite) MTRDeviceControllerXPCProxyHandle * proxyHandle;
@property (strong, nonatomic, readwrite) MTRDeviceControllerXPCProxyHandle * proxyRetainerForReports;
@property (strong, atomic, readonly) dispatch_queue_t workQueue;

@property (strong, nonatomic, readonly) NSMutableDictionary<id, NSMutableDictionary *> * reportRegistry;

@end

@implementation MTRDeviceControllerXPCConnection

- (instancetype)initWithWorkQueue:(dispatch_queue_t)workQueue connectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
    if ([super init]) {
        _remoteDeviceServerProtocol = [MTRDeviceController xpcInterfaceForServerProtocol];
        _remoteDeviceClientProtocol = [MTRDeviceController xpcInterfaceForClientProtocol];
        _connectBlock = connectBlock;
        _workQueue = workQueue;
        _reportRegistry = [[NSMutableDictionary alloc] init];
    }
    return self;
}

// This class method is for unit testing
+ (MTRDeviceControllerXPCConnection *)connectionWithWorkQueue:(dispatch_queue_t)workQueue
                                                 connectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
    return [[MTRDeviceControllerXPCConnection alloc] initWithWorkQueue:workQueue connectBlock:connectBlock];
}

- (void)getProxyHandleWithCompletion:(MTRGetProxyHandleHandler)completion
{
    dispatch_async(_workQueue, ^{
        MTRDeviceControllerXPCProxyHandle * container = self.proxyHandle;
        if (!container) {
            NSXPCConnection * xpcConnection = self.connectBlock();
            if (!xpcConnection) {
                MTR_LOG_ERROR("Cannot connect to XPC server for remote controller");
                completion(self.workQueue, nil);
                return;
            }
            xpcConnection.remoteObjectInterface = self.remoteDeviceServerProtocol;
            xpcConnection.exportedInterface = self.remoteDeviceClientProtocol;
            xpcConnection.exportedObject = self;
            [xpcConnection resume];
            container = [[MTRDeviceControllerXPCProxyHandle alloc] initWithXPCConnection:xpcConnection];
            self.proxyHandle = container;
            __weak typeof(self) weakSelf = self;
            xpcConnection.invalidationHandler = ^{
                typeof(self) strongSelf = weakSelf;
                if (strongSelf) {
                    dispatch_async(strongSelf.workQueue, ^{
                        strongSelf.proxyHandle = nil;
                        strongSelf.proxyRetainerForReports = nil;
                        [strongSelf.reportRegistry removeAllObjects];
                        MTR_LOG_DEBUG("CHIP XPC connection disconnected");
                    });
                }
            };
            MTR_LOG_DEBUG("CHIP XPC connection established");
        }
        completion(self.workQueue, container);
    });
}

- (void)registerReportHandlerWithController:(id<NSCopying>)controller nodeID:(NSNumber *)nodeID handler:(MTRXPCReportHandler)handler
{
    dispatch_async(_workQueue, ^{
        BOOL shouldRetainProxyForReport = ([self.reportRegistry count] == 0);
        NSMutableDictionary * controllerDictionary = self.reportRegistry[controller];
        if (!controllerDictionary) {
            controllerDictionary = [[NSMutableDictionary alloc] init];
            [self.reportRegistry setObject:controllerDictionary forKey:controller];
        }
        NSMutableArray * nodeArray = controllerDictionary[nodeID];
        if (!nodeArray) {
            nodeArray = [[NSMutableArray alloc] init];
            [controllerDictionary setObject:nodeArray forKey:nodeID];
        }
        [nodeArray addObject:handler];
        if (shouldRetainProxyForReport) {
            self.proxyRetainerForReports = self.proxyHandle;
        }
    });
}

- (void)deregisterReportHandlersWithController:(id<NSCopying>)controller
                                        nodeID:(NSNumber *)nodeID
                                    completion:(dispatch_block_t)completion
{
    dispatch_async(_workQueue, ^{
        __auto_type clearRegistry = ^{
            NSMutableDictionary * controllerDictionary = self.reportRegistry[controller];
            if (!controllerDictionary) {
                completion();
                return;
            }
            NSMutableArray * nodeArray = controllerDictionary[nodeID];
            if (!nodeArray) {
                completion();
                return;
            }
            [controllerDictionary removeObjectForKey:nodeID];
            if ([controllerDictionary count] == 0) {
                // Dereference proxy retainer for reports so that XPC connection may be invalidated if no longer used.
                self.proxyRetainerForReports = nil;
            }
            completion();
        };
        [self
            getProxyHandleWithCompletion:^(dispatch_queue_t _Nonnull queue, MTRDeviceControllerXPCProxyHandle * _Nullable handle) {
                if (handle) {
                    MTR_LOG_DEBUG("CHIP XPC connection requests to stop reports");
                    [handle.proxy stopReportsWithController:controller
                                                     nodeId:nodeID.unsignedLongLongValue
                                                 completion:^{
                                                     __auto_type handleRetainer = handle;
                                                     (void) handleRetainer;
                                                     clearRegistry();
                                                 }];
                } else {
                    MTR_LOG_ERROR("CHIP XPC connection failed to stop reporting");
                    clearRegistry();
                }
            }];
    });
}

- (void)handleReportWithController:(id)controller
                            nodeId:(uint64_t)nodeId
                            values:(id _Nullable)values
                             error:(NSError * _Nullable)error
{
    dispatch_async(_workQueue, ^{
        NSMutableDictionary * controllerDictionary = self.reportRegistry[controller];
        if (!controllerDictionary) {
            return;
        }
        NSNumber * nodeIdKey = [NSNumber numberWithUnsignedInteger:nodeId];
        NSMutableArray * nodeArray = controllerDictionary[nodeIdKey];
        if (!nodeArray) {
            return;
        }
        for (void (^handler)(id _Nullable values, NSError * _Nullable error) in nodeArray) {
            handler(values, error);
        }
    });
}

@end
