# Copyright (c) 2021 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.

name: ICD Management Cluster Tests

config:
    nodeId: 0x12344321
    cluster: "ICD Management"
    endpoint: 0
    beforeRebootICDCounter:
        type: int32u
        defaultValue: 0

tests:
    - label: "Read the commissioner node ID"
      cluster: "CommissionerCommands"
      command: "GetCommissionerNodeId"
      response:
          values:
              - name: "nodeId"
                saveAs: commissionerNodeId

    - label: "Wait for the commissioned device to be retrieved"
      cluster: "DelayCommands"
      command: "WaitForCommissionee"
      arguments:
          values:
              - name: "nodeId"
                value: nodeId

    # chip-tool will register itself with the ICD during the tests.
    - label: "Read RegisteredClients For Registration During Commissioning"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value:
              [
                  {
                      CheckInNodeID: commissionerNodeId,
                      MonitoredSubject: commissionerNodeId,
                  },
              ]

    - label: "Read ICDCounter"
      command: "readAttribute"
      attribute: "ICDCounter"
      response:
          constraints:
              type: int32u
              minValue: 0x0
              maxValue: 0xFFFFFFFF
          saveAs: beforeRebootICDCounter

    - label: "Reboot target device"
      cluster: "SystemCommands"
      command: "Reboot"

    - label: "Connect to the device again"
      cluster: "DelayCommands"
      command: "WaitForCommissionee"
      arguments:
          values:
              - name: "nodeId"
                value: nodeId

    - label: "Wait for 1S"
      cluster: "DelayCommands"
      command: "WaitForMs"
      arguments:
          values:
              - name: "ms"
                value: 1000

    # Verifies ICDCounter increment and Check-In message at reboot
    - label: "Read ICDCounter after reboot"
      command: "readAttribute"
      attribute: "ICDCounter"
      response:
          constraints:
              # It is possible ICD hasn't had time to send a Check-In message after reboot
              minValue: beforeRebootICDCounter + 100
              maxValue: beforeRebootICDCounter + 101

    - label: "Verify the ICD is operating as a LIT ICD"
      command: "readAttribute"
      attribute: OperatingMode
      response:
          value: 1

    - label: "Unregister Client Registered During Commissioning"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: commissionerNodeId

    - label: "Verify the ICD is operating as a SIT ICD"
      command: "readAttribute"
      attribute: OperatingMode
      response:
          value: 0

    - label: "Read Feature Map"
      command: "readAttribute"
      attribute: "FeatureMap"
      response:
          value: 0x0F

    - label: "Read IdleModeDuration"
      command: "readAttribute"
      attribute: "IdleModeDuration"
      response:
          value: 3600

    - label: "Read ActiveModeDuration"
      command: "readAttribute"
      attribute: "ActiveModeDuration"
      response:
          value: 10000

    - label: "Read ActiveModeThreshold"
      command: "readAttribute"
      attribute: "ActiveModeThreshold"
      response:
          value: 5000

    - label: "Read UserActiveModeTriggerHint"
      command: "readAttribute"
      attribute: "UserActiveModeTriggerHint"
      response:
          constraints:
              type: bitmap32
          value: 0x111D

    - label: "Read UserActiveModeTriggerInstruction"
      command: "readAttribute"
      attribute: "UserActiveModeTriggerInstruction"
      response:
          constraints:
              type: char_string
              minLength: 1
              maxLength: 128

    - label: "Read ClientsSupportedPerFabric"
      command: "readAttribute"
      attribute: "ClientsSupportedPerFabric"
      response:
          value: 2

    - label: "Unregister 1.0"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
      response:
          error: NOT_FOUND

    - label: "Unregister 2.0"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 102
      response:
          error: NOT_FOUND

    - label: "Unregister 3.0"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 102
      response:
          error: NOT_FOUND

    - label: "Register 1.0 (key too short)"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "MonitoredSubject"
                value: 1001
              - name: "Key"
                value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
              - name: "ClientType"
                value: ClientTypeEnum.Permanent
      response:
          error: CONSTRAINT_ERROR

    - label: "Register 1.0 (key too long)"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "MonitoredSubject"
                value: 1001
              - name: "Key"
                value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\xff"
              - name: "ClientType"
                value: ClientTypeEnum.Permanent
      response:
          error: CONSTRAINT_ERROR

    - label: "Register 1.1 - Invalid ClientType"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "MonitoredSubject"
                value: 1001
              - name: "Key"
                value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
              - name: "ClientType"
                value: ClientTypeEnum.UnknownEnumValue
      response:
          error: CONSTRAINT_ERROR

    - label: "Register 1.2"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "MonitoredSubject"
                value: 1001
              - name: "Key"
                value: "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
              - name: "ClientType"
                value: ClientTypeEnum.Permanent
      response:
          values:
              - name: "ICDCounter"
                constraints:
                    type: int32u
                    minValue: 0x0
                    maxValue: 0xFFFFFFFF

    - label: "Register 2.1"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 201
              - name: "MonitoredSubject"
                value: 2001
              - name: "Key"
                value:
                    "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
              - name: "ClientType"
                value: ClientTypeEnum.Ephemeral
      response:
          values:
              - name: "ICDCounter"
                constraints:
                    type: int32u
                    minValue: 0x0
                    maxValue: 0xFFFFFFFF

    - label: "Register 3.1"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 301
              - name: "MonitoredSubject"
                value: 3001
              - name: "Key"
                value: "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
              - name: "ClientType"
                value: ClientTypeEnum.Permanent
      response:
          error: RESOURCE_EXHAUSTED

    - label: "Read RegisteredClients"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value:
              [
                  {
                      CheckInNodeID: 101,
                      MonitoredSubject: 1001,
                      ClientType: ClientTypeEnum.Permanent,
                  },
                  {
                      CheckInNodeID: 201,
                      MonitoredSubject: 2001,
                      ClientType: ClientTypeEnum.Ephemeral,
                  },
              ]

    - label: "Register 1.1 (update)"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "MonitoredSubject"
                value: 1002
              - name: "Key"
                value: "\x01\x11\x21\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xe1\xf1"
              - name: "ClientType"
                value: ClientTypeEnum.Ephemeral
      response:
          values:
              - name: "ICDCounter"
                constraints:
                    type: int32u
                    minValue: 0x0
                    maxValue: 0xFFFFFFFF

    - label: "Read RegisteredClients"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value:
              [
                  {
                      CheckInNodeID: 101,
                      MonitoredSubject: 1002,
                      ClientType: ClientTypeEnum.Ephemeral,
                  },
                  {
                      CheckInNodeID: 201,
                      MonitoredSubject: 2001,
                      ClientType: ClientTypeEnum.Ephemeral,
                  },
              ]

    - label: "Register 2.2 (wrong verification key)"
      command: "RegisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 201
              - name: "MonitoredSubject"
                value: 2002
              - name: "Key"
                value: "\x02\x12\x22\x32\x42\x52\x62\x72\x82\x92\xa2\xb2\xc2\xd2\xe2\x2f"
              - name: "VerificationKey"
                value:
                    "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2f\x2f"
              - name: "ClientType"
                value: ClientTypeEnum.Permanent
      response:
          values:
              - name: "ICDCounter"
                constraints:
                    type: int32u
                    minValue: 0x0
                    maxValue: 0xFFFFFFFF

    - label: "Read RegisteredClients"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value:
              [
                  {
                      CheckInNodeID: 101,
                      MonitoredSubject: 1002,
                      ClientType: ClientTypeEnum.Ephemeral,
                  },
                  {
                      CheckInNodeID: 201,
                      MonitoredSubject: 2002,
                      ClientType: ClientTypeEnum.Permanent,
                  },
              ]

    - label: "Unregister 1.1 (wrong key)"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
              - name: "VerificationKey"
                value: "\x01\x21\x21\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xe1\xf1"

    - label: "Read RegisteredClients"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value: [{ CheckInNodeID: 201, MonitoredSubject: 2002 }]

    - label: "Unregister 2.1"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 201

    - label: "Read RegisteredClients"
      command: "readAttribute"
      attribute: "RegisteredClients"
      response:
          value: []

    - label: "Unregister 1.3"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 101
      response:
          error: NOT_FOUND

    - label: "Unregister 2.2"
      command: "UnregisterClient"
      arguments:
          values:
              - name: "CheckInNodeID"
                value: 102
      response:
          error: NOT_FOUND

    - label:
          "Wait for a little bit less than the active mode duration (10000ms)"
      cluster: "DelayCommands"
      command: "WaitForMs"
      arguments:
          values:
              - name: "ms"
                value: 9000

    - label:
          "StayActive Scenario 1: Confirm the promised active duration is
          increased to a specific if a value less than 30000ms is requested and
          the device does not intend to stay active longer"
      command: "StayActiveRequest"
      arguments:
          values:
              - name: "StayActiveDuration"
                value: 20000
      response:
          values:
              - name: "PromisedActiveDuration"
                constraints:
                    type: int32u
                    minValue: 19500
                    maxValue: 20500

    - label:
          "Wait for a little bit less than the new promied active mode duration
          (20000ms)"
      cluster: "DelayCommands"
      command: "WaitForMs"
      arguments:
          values:
              - name: "ms"
                value: 19000

    - label:
          "StayActive Scenario 2: Confirm the promised active duration is
          reduced to 30000ms if a value greater than 30000ms is requested"
      command: "StayActiveRequest"
      arguments:
          values:
              - name: "StayActiveDuration"
                value: 35000
      response:
          values:
              - name: "PromisedActiveDuration"
                constraints:
                    type: int32u
                    minValue: 29500
                    maxValue: 30500

    - label:
          "Wait for a 20000 less than the new promied active mode duration
          (30000ms)"
      cluster: "DelayCommands"
      command: "WaitForMs"
      arguments:
          values:
              - name: "ms"
                value: 10000

    - label:
          "StayActive Scenario 3: confirm that the device ignores the request if
          the device intends to stay active longer than the requested duration
          we should have about 20000ms left here"
      command: "StayActiveRequest"
      arguments:
          values:
              - name: "StayActiveDuration"
                value: 10000
      response:
          values:
              - name: "PromisedActiveDuration"
                constraints:
                    type: int32u
                    minValue: 19500
                    maxValue: 20500
