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

#import "MTRBaseDevice_Internal.h"
#import "MTRCluster.h"
#import "MTRClusterStateCacheContainer_Internal.h"
#import "MTRDeviceControllerXPCConnection.h"
#import "MTRDeviceController_Internal.h"
#import "MTRError.h"
#import "MTRError_Internal.h"
#import "MTRLogging_Internal.h"

#include <app/InteractionModelEngine.h>
#include <lib/support/ErrorStr.h>
#include <platform/PlatformManager.h>

using namespace chip;

@interface MTRClusterStateCacheContainer ()
@property (nonatomic, readwrite, copy) NSNumber * deviceID;
@property (nonatomic, readwrite, weak, nullable) MTRDeviceControllerXPCConnection * xpcConnection;
@property (nonatomic, readwrite, strong, nullable) id<NSCopying> xpcControllerID;
@property (atomic, readwrite) BOOL shouldUseXPC;
@end

@implementation MTRClusterStateCacheContainer

- (instancetype)init
{
    if ([super init]) {
        _cppClusterStateCache = nullptr;
        _baseDevice = nil;
        _shouldUseXPC = NO;
    }
    return self;
}

- (void)setXPCConnection:(MTRDeviceControllerXPCConnection *)xpcConnection
            controllerID:(id<NSCopying>)controllerID
                deviceID:(NSNumber *)deviceID
{
    self.xpcConnection = xpcConnection;
    self.xpcControllerID = controllerID;
    self.deviceID = deviceID;
    self.shouldUseXPC = YES;
}

static CHIP_ERROR AppendAttributeValueToArray(
    const chip::app::ConcreteAttributePath & path, chip::app::ClusterStateCache * cache, NSMutableArray * array)
{
    chip::TLV::TLVReader reader;
    CHIP_ERROR err = cache->Get(path, reader);
    if (err == CHIP_NO_ERROR) {
        id obj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader);
        if (obj) {
            [array addObject:@ { MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:path], MTRDataKey : obj }];
            return CHIP_NO_ERROR;
        }
        MTR_LOG_ERROR("Error: Cached value could not be converted to generic NSObject");
        [array addObject:@ {
            MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:path],
            MTRErrorKey : [MTRError errorForCHIPErrorCode:CHIP_ERROR_DECODE_FAILED]
        }];
        return CHIP_ERROR_DECODE_FAILED;
    }
    MTR_LOG_ERROR("Error: Failed to read from attribute cache: %s", err.AsString());
    [array addObject:@ {
        MTRAttributePathKey : [[MTRAttributePath alloc] initWithPath:path],
        MTRErrorKey : [MTRError errorForCHIPErrorCode:err]
    }];
    return err;
}

- (void)readAttributesWithEndpointID:(NSNumber * _Nullable)endpointID
                           clusterID:(NSNumber * _Nullable)clusterID
                         attributeID:(NSNumber * _Nullable)attributeID
                               queue:(dispatch_queue_t)queue
                          completion:(MTRDeviceResponseHandler)completion
{
    __auto_type completionHandler = ^(NSArray<NSDictionary<NSString *, id> *> * _Nullable values, NSError * _Nullable error) {
        dispatch_async(queue, ^{
            completion(values, error);
        });
    };

    if (self.shouldUseXPC) {
        MTRDeviceControllerXPCConnection * xpcConnection = self.xpcConnection;
        if (!xpcConnection) {
            MTR_LOG_ERROR("Attribute cache read failed: MTRDeviceController was already disposed");
            completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
            return;
        }
        __auto_type controllerId = self.xpcControllerID;
        NSNumber * nodeId = self.deviceID;
        [xpcConnection
            getProxyHandleWithCompletion:^(dispatch_queue_t _Nonnull queue, MTRDeviceControllerXPCProxyHandle * _Nullable handle) {
                if (handle) {
                    [handle.proxy
                        readAttributeCacheWithController:controllerId
                                                  nodeId:nodeId.unsignedLongLongValue
                                              endpointId:endpointID
                                               clusterId:clusterID
                                             attributeId:attributeID
                                              completion:^(id _Nullable values, NSError * _Nullable error) {
                                                  completionHandler([MTRDeviceController decodeXPCResponseValues:values], error);
                                                  __auto_type handleRetainer = handle;
                                                  (void) handleRetainer;
                                              }];
                } else {
                    MTR_LOG_ERROR("Attribute cache read failed due to XPC connection failure");
                    completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
                }
            }];
        return;
    }

    if (!self.baseDevice) {
        MTR_LOG_ERROR("Error: No attribute cache available to read from");
        completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
        return;
    }

    [self.baseDevice.deviceController
        asyncDispatchToMatterQueue:^(Controller::DeviceCommissioner *) {
            if (endpointID == nil && clusterID == nil) {
                MTR_LOG_ERROR(
                    "Error: currently read from attribute cache does not support wildcards for both endpoint and cluster");
                completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeInvalidArgument userInfo:nil]);
                return;
            }

            if (!self.cppClusterStateCache) {
                MTR_LOG_ERROR("Error: No attribute cache available to read from");
                completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
                return;
            }

            NSMutableArray * result = [[NSMutableArray alloc] init];
            CHIP_ERROR err = CHIP_NO_ERROR;
            if (endpointID == nil) {
                err = self.cppClusterStateCache->ForEachAttribute(
                    static_cast<chip::ClusterId>([clusterID unsignedLongValue]), [&](const app::ConcreteAttributePath & path) {
                        if (attributeID == nil
                            || static_cast<chip::AttributeId>([attributeID unsignedLongValue]) == path.mAttributeId) {
                            (void) AppendAttributeValueToArray(path, self.cppClusterStateCache, result);
                        }
                        return CHIP_NO_ERROR;
                    });
            } else if (clusterID == nil) {
                err = self.cppClusterStateCache->ForEachCluster(
                    static_cast<chip::EndpointId>([endpointID unsignedShortValue]), [&](chip::ClusterId enumeratedClusterId) {
                        (void) self.cppClusterStateCache->ForEachAttribute(
                            static_cast<chip::EndpointId>([endpointID unsignedShortValue]), enumeratedClusterId,
                            [&](const app::ConcreteAttributePath & path) {
                                if (attributeID == nil
                                    || static_cast<chip::AttributeId>([attributeID unsignedLongValue]) == path.mAttributeId) {
                                    (void) AppendAttributeValueToArray(path, self.cppClusterStateCache, result);
                                }
                                return CHIP_NO_ERROR;
                            });
                        return CHIP_NO_ERROR;
                    });
            } else if (attributeID == nil) {
                err = self.cppClusterStateCache->ForEachAttribute(static_cast<chip::EndpointId>([endpointID unsignedShortValue]),
                    static_cast<chip::ClusterId>([clusterID unsignedLongValue]), [&](const app::ConcreteAttributePath & path) {
                        (void) AppendAttributeValueToArray(path, self.cppClusterStateCache, result);
                        return CHIP_NO_ERROR;
                    });
            } else {
                app::ConcreteAttributePath path;
                path.mEndpointId = static_cast<chip::EndpointId>([endpointID unsignedShortValue]);
                path.mClusterId = static_cast<chip::ClusterId>([clusterID unsignedLongValue]);
                path.mAttributeId = static_cast<chip::AttributeId>([attributeID unsignedLongValue]);
                err = AppendAttributeValueToArray(path, self.cppClusterStateCache, result);
            }
            if (err == CHIP_NO_ERROR) {
                completionHandler(result, nil);
            } else {
                completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:err.AsInteger() userInfo:nil]);
            }
        }
        errorHandler:^(NSError * error) {
            completionHandler(nil, error);
        }];
}

@end

@implementation MTRAttributeCacheContainer

- (instancetype)init
{
    if (self = [super init]) {
        _realContainer = [[MTRClusterStateCacheContainer alloc] init];
        if (_realContainer == nil) {
            return nil;
        }
    }
    return self;
}

- (void)readAttributeWithEndpointId:(NSNumber * _Nullable)endpointId
                          clusterId:(NSNumber * _Nullable)clusterId
                        attributeId:(NSNumber * _Nullable)attributeId
                        clientQueue:(dispatch_queue_t)clientQueue
                         completion:(MTRDeviceResponseHandler)completion
{
    [self.realContainer readAttributesWithEndpointID:endpointId
                                           clusterID:clusterId
                                         attributeID:attributeId
                                               queue:clientQueue
                                          completion:completion];
}

@end
