import Matter
import XCTest

// This should eventually grow into a Swift copy of MTRDeviceTests

// Fixture: chip-all-clusters-app --KVS "$(mktemp -t chip-test-kvs)" --interface-id -1

struct DeviceConstants {
    static let testVendorID = 0xFFF1
    static let onboardingPayload = "MT:-24J0AFN00KA0648G00"
    static let deviceID = 0x12344321
    static let timeoutInSeconds : Double = 3
    static let pairingTimeoutInSeconds : Double = 10
}

var sConnectedDevice: MTRBaseDevice? = nil

var sController: MTRDeviceController? = nil

var sTestKeys: MTRTestKeys? = nil

class MTRSwiftDeviceTestControllerDelegate : NSObject, MTRDeviceControllerDelegate {
    let expectation: XCTestExpectation

    init(withExpectation providedExpectation: XCTestExpectation) {
        expectation = providedExpectation
    }

    func controller(_ controller: MTRDeviceController, statusUpdate status: MTRCommissioningStatus) {
        XCTAssertNotEqual(status, MTRCommissioningStatus.failed)
    }

    func controller(_ controller: MTRDeviceController, commissioningSessionEstablishmentDone error: Error?) {
        XCTAssertNil(error)

        do {
            try controller.commissionNode(withID: DeviceConstants.deviceID as NSNumber, commissioningParams: MTRCommissioningParameters())
        } catch {
            XCTFail("Could not start commissioning of node: \(error)")
        }

        // Keep waiting for commissioningComplete
    }

    func controller(_ controller: MTRDeviceController, commissioningComplete error: Error?, nodeID: NSNumber?) {
        XCTAssertNil(error)
        XCTAssertEqual(nodeID, DeviceConstants.deviceID as NSNumber)
        sConnectedDevice = MTRBaseDevice(nodeID: nodeID!, controller: controller)
        expectation.fulfill()
    }
}

typealias MTRDeviceTestDelegateDataHandler = ([[ String: Any ]]) -> Void

class MTRSwiftDeviceTestDelegate : NSObject, MTRDeviceDelegate {
    var onReachable : () -> Void
    var onNotReachable : (() -> Void)? = nil
    var onAttributeDataReceived : MTRDeviceTestDelegateDataHandler? = nil
    var onEventDataReceived : MTRDeviceTestDelegateDataHandler? = nil
    var onReportEnd : (() -> Void)? = nil

    init(withReachableHandler handler : @escaping () -> Void) {
        onReachable = handler
    }

    func device(_ device: MTRDevice, stateChanged state : MTRDeviceState) {
        if (state == MTRDeviceState.reachable) {
           onReachable()
        } else {
           onNotReachable?()
        }
    }

    func device(_ device : MTRDevice, receivedAttributeReport attributeReport : [[ String: Any ]])
    {
        onAttributeDataReceived?(attributeReport)
    }

    func device(_ device : MTRDevice, receivedEventReport eventReport : [[ String : Any ]])
    {
        onEventDataReceived?(eventReport)
    }

    @objc func unitTestReportEnd(forDevice : MTRDevice)
    {
        onReportEnd?()
    }

    @objc func unitTestMaxIntervalOverrideForSubscription(_ device : MTRDevice) -> NSNumber
    {
      // Make sure our subscriptions time out in finite time.
      return 2; // seconds
    }

}

class MTRSwiftDeviceTests : XCTestCase {
    static override func setUp()
    {
        super.setUp()

        let factory = MTRDeviceControllerFactory.sharedInstance()
        
        let storage = MTRTestStorage()
        let factoryParams = MTRDeviceControllerFactoryParams(storage: storage)
        
        do {
            try factory.start(factoryParams)
        } catch {
            XCTFail("Count not start controller factory: \(error)")
        }
        XCTAssertTrue(factory.isRunning)
        
        let testKeys = MTRTestKeys()
        sTestKeys = testKeys
        
        // Needs to match what startControllerOnExistingFabric calls elsewhere in
        // this file do.
        let params = MTRDeviceControllerStartupParams(ipk: testKeys.ipk, fabricID: 1, nocSigner:testKeys)
        params.vendorID = DeviceConstants.testVendorID as NSNumber
        
        let controller : MTRDeviceController
        do {
            controller = try factory.createController(onNewFabric: params)
        } catch {
            XCTFail("Could not create controller: \(error)")
            return
        }
        XCTAssertTrue(controller.isRunning)
        
        sController = controller
        
        let expectation = XCTestExpectation(description : "Commissioning Complete")

        let controllerDelegate = MTRSwiftDeviceTestControllerDelegate(withExpectation: expectation)
        let serialQueue = DispatchQueue(label: "com.chip.device_controller_delegate")
        
        controller.setDeviceControllerDelegate(controllerDelegate, queue: serialQueue)
        
        let payload : MTRSetupPayload
        do {
            payload = try MTRSetupPayload(onboardingPayload: DeviceConstants.onboardingPayload)
        } catch {
            XCTFail("Could not parse setup payload: \(error)")
            return
        }
        
        do {
            try controller.setupCommissioningSession(with:payload, newNodeID: DeviceConstants.deviceID as NSNumber)
        } catch {
            XCTFail("Could not start setting up PASE session: \(error)")
            return        }

        XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: DeviceConstants.pairingTimeoutInSeconds), XCTWaiter.Result.completed)
    }
    
    static override func tearDown() {
        ResetCommissionee(sConnectedDevice, DispatchQueue.main, nil, UInt16(DeviceConstants.timeoutInSeconds))

        let controller = sController
        XCTAssertNotNil(controller)
        controller!.shutdown()
        XCTAssertFalse(controller!.isRunning)
        
        MTRDeviceControllerFactory.sharedInstance().stop()

        super.tearDown()
    }

    override func setUp()
    {
        super.setUp()
        self.continueAfterFailure = false
    }

    func test017_TestMTRDeviceBasics()
    {
        let device = MTRDevice(nodeID: DeviceConstants.deviceID as NSNumber, controller:sController!)
        let queue = DispatchQueue.main
        
        // Given reachable state becomes true before underlying OnSubscriptionEstablished callback, this expectation is necessary but
        // not sufficient as a mark to the end of reports
        let subscriptionExpectation = expectation(description: "Subscription has been set up")
        
        let delegate = MTRSwiftDeviceTestDelegate(withReachableHandler: { () -> Void in
            subscriptionExpectation.fulfill()
        })
        
        var attributeReportsReceived : Int = 0
        delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in
            attributeReportsReceived += data.count
        }
        
        // This is dependent on current implementation that priming reports send attributes and events in that order, and also that
        // events in this test would fit in one report. So receiving events would mean all attributes and events have been received, and
        // can satisfy the test below.
        let gotReportsExpectation = expectation(description: "Attribute and Event reports have been received")
        var eventReportsReceived : Int = 0
        delegate.onEventDataReceived = { (eventReport: [[ String: Any ]]) -> Void in
            eventReportsReceived += eventReport.count
            
            for eventDict in eventReport {
                let eventTimeTypeNumber = eventDict[MTREventTimeTypeKey] as! NSNumber?
                XCTAssertNotNil(eventTimeTypeNumber)
                let eventTimeType = MTREventTimeType(rawValue: eventTimeTypeNumber!.uintValue)
                XCTAssert((eventTimeType == MTREventTimeType.systemUpTime) || (eventTimeType == MTREventTimeType.timestampDate))
                if (eventTimeType == MTREventTimeType.systemUpTime) {
                    XCTAssertNotNil(eventDict[MTREventSystemUpTimeKey])
                    XCTAssertNotNil(device.estimatedStartTime)
                } else if (eventTimeType == MTREventTimeType.timestampDate) {
                    XCTAssertNotNil(eventDict[MTREventTimestampDateKey])
                }
            }
        }
        delegate.onReportEnd = { () -> Void in
            gotReportsExpectation.fulfill()
        }
        
        device.setDelegate(_: delegate, queue:queue)
        
        // Test batching and duplicate check
        //   - Read 13 different attributes in a row, expect that the 1st to go out by itself, the next 9 batch, and then the 3 after
        //     are correctly queued in one batch
        //   - Then read 3 duplicates and expect them to be filtered
        //   - Note that these tests can only be verified via logs
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 0, params: nil)
        
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 1, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 2, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 3, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 4, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 5, params: nil)
        
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 6, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.colorControlID.rawValue), attributeID: 7, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 0, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 1, params: nil)
        
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 2, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 3, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 4, params: nil)
        
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 4, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 4, params: nil)
        device.readAttribute(withEndpointID: 1, clusterID: NSNumber(value: MTRClusterIDType.levelControlID.rawValue), attributeID: 4, params: nil)
        
        wait(for: [ subscriptionExpectation, gotReportsExpectation ], timeout:60)
        
        delegate.onReportEnd = nil
        
        XCTAssertNotEqual(attributeReportsReceived, 0)
        XCTAssertNotEqual(eventReportsReceived, 0)
        
        // Before resubscribe, first test write failure and expected value effects
        let testEndpointID = 1 as NSNumber
        let testClusterID = 8 as NSNumber
        let testAttributeID = 10000 as NSNumber // choose a nonexistent attribute to cause a failure
        let expectedValueReportedExpectation = expectation(description: "Expected value reported")
        let expectedValueRemovedExpectation =    expectation(description: "Expected value removed")
        delegate.onAttributeDataReceived = { (attributeReport: [[ String: Any ]]) -> Void in
            for attributeDict in attributeReport {
                let attributePath = attributeDict[MTRAttributePathKey] as! MTRAttributePath
                XCTAssertNotNil(attributePath)
                if (attributePath.endpoint == testEndpointID &&
                    attributePath.cluster == testClusterID &&
                    attributePath.attribute == testAttributeID) {
                    let data = attributeDict[MTRDataKey]
                    if (data != nil) {
                        expectedValueReportedExpectation.fulfill()
                    } else {
                        expectedValueRemovedExpectation.fulfill()
                    }
                }
            }
        }
        
        let writeValue = [ "type": "UnsignedInteger", "value": 200 ] as [String: Any]
        device.writeAttribute(withEndpointID: testEndpointID,
                              clusterID: testClusterID,
                              attributeID: testAttributeID,
                              value: writeValue,
                              expectedValueInterval: 20000,
                              timedWriteTimeout:nil)
        
        // expected value interval is 20s but expect it get reverted immediately as the write fails because it's writing to a
        // nonexistent attribute
        wait(for: [ expectedValueReportedExpectation, expectedValueRemovedExpectation ], timeout: 5, enforceOrder: true)
        
        // Test if errors are properly received
        // TODO: We might stop reporting these altogether from MTRDevice, and then
        // this test will need updating.
        let readThroughForUnknownAttributesParams = MTRReadParams()
        readThroughForUnknownAttributesParams.shouldAssumeUnknownAttributesReportable = false;
        let attributeReportErrorExpectation = expectation(description: "Attribute read error")
        delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in
            for attributeReponseValue in data {
                if (attributeReponseValue[MTRErrorKey] != nil) {
                    attributeReportErrorExpectation.fulfill()
                }
            }
        }
        // use the nonexistent attribute and expect read error
        device.readAttribute(withEndpointID: testEndpointID, clusterID: testClusterID, attributeID: testAttributeID, params: readThroughForUnknownAttributesParams)
        wait(for: [ attributeReportErrorExpectation ], timeout: 10)
        
        // Resubscription test setup
        let subscriptionDroppedExpectation = expectation(description: "Subscription has dropped")
        delegate.onNotReachable = { () -> Void in
            subscriptionDroppedExpectation.fulfill()
        };
        let resubscriptionExpectation = expectation(description: "Resubscription has happened")
        delegate.onReachable = { () -> Void in
            resubscriptionExpectation.fulfill()
        };
        
        // reset the onAttributeDataReceived to validate the following resubscribe test
        attributeReportsReceived = 0;
        eventReportsReceived = 0;
        delegate.onAttributeDataReceived = { (data: [[ String: Any ]]) -> Void in
            attributeReportsReceived += data.count;
        };
        
        delegate.onEventDataReceived = { (eventReport: [[ String: Any ]]) -> Void in
            eventReportsReceived += eventReport.count;
        };
        
        // Now trigger another subscription which will cause ours to drop; we should re-subscribe after that.
        let baseDevice = sConnectedDevice
        let params = MTRSubscribeParams(minInterval: 1, maxInterval: 2)
        params.shouldResubscribeAutomatically = false;
        params.shouldReplaceExistingSubscriptions = true;
        // Create second subscription which will cancel the first subscription.  We
        // can use a non-existent path here to cut down on the work that gets done.
        baseDevice?.subscribeToAttributes(withEndpointID: 10000,
                                          clusterID: 6,
                                          attributeID: 0,
                                          params: params,
                                          queue: queue,
                                          reportHandler: { (_: [[String : Any]]?, _: Error?) -> Void in
        })
        
        wait(for: [ subscriptionDroppedExpectation ], timeout:60)
        
        // Check that device resets start time on subscription drop
        XCTAssertNil(device.estimatedStartTime)
        
        wait(for: [ resubscriptionExpectation ], timeout:60)
        
        // Now make sure we ignore later tests.  Ideally we would just unsubscribe
        // or remove the delegate, but there's no good way to do that.
        delegate.onReachable = { () -> Void in }
        delegate.onNotReachable = nil
        delegate.onAttributeDataReceived = nil
        delegate.onEventDataReceived = nil
        
        // Make sure we got no updated reports (because we had a cluster state cache
        // with data versions) during the resubscribe.
        XCTAssertEqual(attributeReportsReceived, 0);
        XCTAssertEqual(eventReportsReceived, 0);
    }
    
    func test018_SubscriptionErrorWhenNotResubscribing()
    {
        let device = sConnectedDevice!
        let queue = DispatchQueue.main
        
        let firstSubscribeExpectation = expectation(description: "First subscription complete")
        let errorExpectation = expectation(description: "First subscription errored out")
        
        // Subscribe
        let params = MTRSubscribeParams(minInterval: 1, maxInterval: 10)
        params.shouldResubscribeAutomatically = false
        params.shouldReplaceExistingSubscriptions = true // Not strictly needed, but checking that doing this does not
        // affect this subscription erroring out correctly.
        var subscriptionEstablished = false
        device.subscribeToAttributes(withEndpointID: 1,
                                     clusterID: 6,
                                     attributeID: 0,
                                     params: params,
                                     queue: queue,
                                     reportHandler: { values, error in
            if (subscriptionEstablished) {
                // We should only get an error here.
                XCTAssertNil(values)
                XCTAssertNotNil(error)
                errorExpectation.fulfill()
            } else {
                XCTAssertNotNil(values)
                XCTAssertNil(error)
            }
        },
                                     subscriptionEstablished: {
            NSLog("subscribe attribute: OnOff established")
            XCTAssertFalse(subscriptionEstablished)
            subscriptionEstablished = true
            firstSubscribeExpectation.fulfill()
        })
        
        // Wait till establishment
        wait(for: [ firstSubscribeExpectation ], timeout: DeviceConstants.timeoutInSeconds)
        
        // Create second subscription which will cancel the first subscription.  We
        // can use a non-existent path here to cut down on the work that gets done.
        params.shouldReplaceExistingSubscriptions = true
        
        device.subscribeToAttributes(withEndpointID: 10000,
                                     clusterID: 6,
                                     attributeID: 0,
                                     params: params,
                                     queue: queue,
                                     reportHandler: { _, _ in
        })
        wait(for: [ errorExpectation ], timeout: 60)
    }
    
    func test019_MTRDeviceMultipleCommands() async
    {
        let device = MTRDevice(nodeID: DeviceConstants.deviceID as NSNumber, controller:sController!)
        let queue = DispatchQueue.main
        
        let opcredsCluster = MTRClusterOperationalCredentials(device: device, endpointID: 0, queue: queue)!
        let onOffCluster = MTRClusterOnOff(device: device, endpointID: 1, queue: queue)!
        let badOnOffCluster = MTRClusterOnOff(device: device, endpointID: 0, queue: queue)!
        
        // Ensure our existing fabric label is not "Test".  This uses a "base"
        // cluster to ensure read-through to the other side.
        let baseOpCredsCluster = MTRBaseClusterOperationalCredentials(device: sConnectedDevice!, endpointID: 0, queue: queue)!
        var fabricList = try! await baseOpCredsCluster.readAttributeFabrics(with: nil)
        XCTAssertEqual(fabricList.count, 1)
        var entry = fabricList[0] as! MTROperationalCredentialsClusterFabricDescriptorStruct
        XCTAssertNotEqual(entry.label, "Test")
        
        let currentFabricIndex = try! await baseOpCredsCluster.readAttributeCurrentFabricIndex()
        
        // NOTE: The command invocations do not use "await", because we actually want
        // to do them all sort of in parallel, or at least queue them all on the MTRDevice
        // before we get a chance to finish the first one.
        let onExpectation = expectation(description: "On command executed")
        onOffCluster.on(withExpectedValues: nil, expectedValueInterval: nil) { error in
            XCTAssertNil(error)
            onExpectation.fulfill()
        }
        
        let offFailedExpectation = expectation(description: "Off command failed")
        badOnOffCluster.off(withExpectedValues: nil, expectedValueInterval: nil) { error in
            XCTAssertNotNil(error)
            offFailedExpectation.fulfill()
        }
        
        let updateLabelExpectation = expectation(description: "Fabric label updated")
        let params = MTROperationalCredentialsClusterUpdateFabricLabelParams()
        params.label = "Test"
        opcredsCluster.updateFabricLabel(with: params, expectedValues: nil, expectedValueInterval: nil) { data, error in
            XCTAssertNil(error)
            XCTAssertNotNil(data)
            XCTAssertEqual(data?.statusCode, 0)
            XCTAssertEqual(data?.fabricIndex, currentFabricIndex)
            updateLabelExpectation.fulfill()
        }
        
        let offExpectation = expectation(description: "Off command executed")
        // Send this one via MTRDevice, to test that codepath
        device.invokeCommand(withEndpointID: 1,
                             clusterID: NSNumber(value: MTRClusterIDType.onOffID.rawValue),
                             commandID: NSNumber(value: MTRCommandIDType.clusterOnOffCommandOffID.rawValue),
                             commandFields: nil,
                             expectedValues: nil,
                             expectedValueInterval: nil,
                             queue: queue) { data, error in
            XCTAssertNil(error)
            offExpectation.fulfill()
        }
        
        let onFailedExpectation = expectation(description: "On command failed")
        badOnOffCluster.on(withExpectedValues: nil, expectedValueInterval: nil) { error in
            XCTAssertNotNil(error)
            onFailedExpectation.fulfill()
        }
        
        let updateLabelFailedExpectation = expectation(description: "Fabric label update failed")
        params.label = "12345678901234567890123445678901234567890" // Too long
        opcredsCluster.updateFabricLabel(with: params,
                                         expectedValues: nil,
                                         expectedValueInterval: nil) { data, error in
            XCTAssertNotNil(error)
            XCTAssertNil(data)
            updateLabelFailedExpectation.fulfill()
        }
        
        wait(for: [ onExpectation,
                    offFailedExpectation,
                    updateLabelExpectation,
                    offExpectation,
                    onFailedExpectation,
                    updateLabelFailedExpectation ],
             timeout: 60,
             enforceOrder: true)
        
        // Now make sure our fabric label got updated.
        fabricList = try! await baseOpCredsCluster.readAttributeFabrics(with: nil)
        XCTAssertNotNil(fabricList)
        XCTAssertEqual(fabricList.count, 1)
        entry = fabricList[0] as! MTROperationalCredentialsClusterFabricDescriptorStruct
        XCTAssertEqual(entry.label, "Test")
    }
    
    // Note: test027_AttestationChallenge is not implementable in Swift so far,
    // because the attestationChallenge property is internal-only
    
    func test030_DeviceAndClusterProperties() {
        let queue = DispatchQueue.main

        let device = MTRDevice(nodeID: DeviceConstants.deviceID as NSNumber, controller:sController!)
        XCTAssertEqual(device.deviceController, sController)
        XCTAssertEqual(device.__nodeID, DeviceConstants.deviceID as NSNumber)
        
        let cluster = MTRClusterOperationalCredentials(device: device, endpointID: 0, queue: queue)!
        XCTAssertEqual(cluster.device, device)
        XCTAssertEqual(cluster.__endpointID, 0 as NSNumber)
    }
}
