# Copyright (c) 2009-2021 Arm Limited
# SPDX-License-Identifier: Apache-2.0
#
# 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 pytest
from time import sleep

from chip import ChipDeviceCtrl

from common.utils import *

from common.pigweed_client import PigweedClient
from device_service import device_service_pb2
from button_service import button_service_pb2
from lighting_service import lighting_service_pb2
from pw_status import Status

import logging
log = logging.getLogger(__name__)

BLE_DEVICE_NAME = "MBED-lighting"
DEVICE_NODE_ID = 1234
TEST_BRIGHTNESS_LEVEL = 200
RPC_PROTOS = [device_service_pb2, button_service_pb2, lighting_service_pb2]


@pytest.mark.smoketest
def test_smoke_test(device):
    device.reset(duration=1)
    ret = device.wait_for_output("Mbed lighting-app example application start")
    assert ret != None and len(ret) > 0
    ret = device.wait_for_output("Mbed lighting-app example application run")
    assert ret != None and len(ret) > 0


def test_wifi_provisioning(device, network):
    network_ssid = network[0]
    network_pass = network[1]

    devCtrl = ChipDeviceCtrl.ChipDeviceController()

    device_details = get_device_details(device)
    assert device_details != None and len(device_details) != 0

    assert check_chip_ble_devices_advertising(
        devCtrl, BLE_DEVICE_NAME, device_details)

    ret = connect_device_over_ble(devCtrl, int(device_details["Discriminator"]), int(
        device_details["SetUpPINCode"]), DEVICE_NODE_ID)
    assert ret != None and ret == DEVICE_NODE_ID

    ret = device.wait_for_output("Device completed Rendezvous process")
    assert ret != None and len(ret) > 0

    ret = commissioning_wifi(devCtrl, network_ssid,
                             network_pass, DEVICE_NODE_ID)
    assert ret == 0

    ret = device.wait_for_output("StationConnected")
    assert ret != None and len(ret) > 0

    ret = device.wait_for_output("address set")
    assert ret != None and len(ret) > 0

    device_ip_address = ret[-1].partition("address set:")[2].strip()

    ret = resolve_device(devCtrl, DEVICE_NODE_ID)
    assert ret != None and len(ret) == 2

    ip_address = ret[0]
    port = ret[1]

    assert device_ip_address == ip_address

    assert close_connection(devCtrl, DEVICE_NODE_ID)
    assert close_ble(devCtrl)


def test_light_ctrl(device, network):
    network_ssid = network[0]
    network_pass = network[1]

    devCtrl = ChipDeviceCtrl.ChipDeviceController()

    device_details = get_device_details(device)
    assert device_details != None and len(device_details) != 0

    assert check_chip_ble_devices_advertising(
        devCtrl, BLE_DEVICE_NAME, device_details)

    ret = connect_device_over_ble(devCtrl, int(device_details["Discriminator"]), int(
        device_details["SetUpPINCode"]), DEVICE_NODE_ID)
    assert ret != None and ret == DEVICE_NODE_ID

    ret = device.wait_for_output("Device completed Rendezvous process")
    assert ret != None and len(ret) > 0

    ret = commissioning_wifi(devCtrl, network_ssid,
                             network_pass, DEVICE_NODE_ID)
    assert ret == 0

    ret = resolve_device(devCtrl, DEVICE_NODE_ID)
    assert ret != None and len(ret) == 2

    err, res = send_zcl_command(
        devCtrl, "OnOff On {} 1 0".format(DEVICE_NODE_ID))
    assert err == 0

    ret = device.wait_for_output("Turn On Action has been completed", 20)
    assert ret != None and len(ret) > 0

    err, res = send_zcl_command(
        devCtrl, "OnOff Off {} 1 0".format(DEVICE_NODE_ID))
    assert err == 0

    ret = device.wait_for_output("Turn Off Action has been completed", 20)
    assert ret != None and len(ret) > 0

    err, res = send_zcl_command(
        devCtrl, "OnOff Toggle {} 1 0".format(DEVICE_NODE_ID))
    assert err == 0

    ret = device.wait_for_output("Turn On Action has been completed", 20)
    assert ret != None and len(ret) > 0

    err, res = send_zcl_command(devCtrl, "LevelControl MoveToLevel {} 1 0 level={} transitionTime=1 optionMask=0 optionOverride=0".format(
        DEVICE_NODE_ID, TEST_BRIGHTNESS_LEVEL))
    assert err == 0

    ret = device.wait_for_output(
        "Setting brightness level to {}".format(TEST_BRIGHTNESS_LEVEL), 20)
    assert ret != None and len(ret) > 0

    assert close_connection(devCtrl, DEVICE_NODE_ID)
    assert close_ble(devCtrl)


def test_device_info_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)
    status, payload = pw_client.rpcs.chip.rpc.Device.GetDeviceInfo()
    assert status.ok() == True
    assert payload.vendor_id != None and payload.product_id != None and payload.serial_number != None

    device_details = get_device_details(device)
    assert device_details != None and len(device_details) != 0

    assert int(device_details["VendorID"]) == payload.vendor_id
    assert int(device_details["ProductID"]) == payload.product_id
    assert int(device_details["Discriminator"]
               ) == payload.pairing_info.discriminator
    assert int(device_details["SetUpPINCode"]) == payload.pairing_info.code


def test_device_factory_reset_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)
    status, payload = pw_client.rpcs.chip.rpc.Device.FactoryReset()
    assert status.ok() == True


def test_device_reboot_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)
    status, payload = pw_client.rpcs.chip.rpc.Device.Reboot()
    assert status == Status.UNIMPLEMENTED


def test_device_ota_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)
    status, payload = pw_client.rpcs.chip.rpc.Device.TriggerOta()
    assert status == Status.UNIMPLEMENTED


def test_ligth_ctrl_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)

    # Check light on
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Set(on=True)
    assert status.ok() == True
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Get()
    assert status.ok() == True
    assert payload.on == True

    # Check light off
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Set(on=False)
    assert status.ok() == True
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Get()
    assert status.ok() == True
    assert payload.on == False


def test_button_ctrl_rpc(device):
    pw_client = PigweedClient(device, RPC_PROTOS)

    # Check button 0 (lighting)
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Get()
    assert status.ok() == True
    initial_state = bool(payload.on)

    compare_state = not initial_state
    status, payload = pw_client.rpcs.chip.rpc.Button.Event(idx=0, pushed=True)
    assert status.ok() == True
    sleep(2)
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Get()
    assert status.ok() == True
    assert payload.on == compare_state

    compare_state = initial_state
    status, payload = pw_client.rpcs.chip.rpc.Button.Event(idx=0, pushed=True)
    assert status.ok() == True
    sleep(2)
    status, payload = pw_client.rpcs.chip.rpc.Lighting.Get()
    assert status.ok() == True
    assert payload.on == compare_state
