# 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
import re
from packaging import version
from time import sleep

from chip.setup_payload import SetupPayload
from chip import exceptions
import chip.native

from common.utils import *

import logging
log = logging.getLogger(__name__)


@pytest.fixture(scope="session")
def binaryPath(request, rootDir):
    if request.config.getoption('binaryPath'):
        return request.config.getoption('binaryPath')
    else:
        return os.path.join(rootDir, 'examples/shell/openiotsdk/build/chip-openiotsdk-shell-example.elf')


SHELL_COMMAND_NAME = ["base64", "exit", "help", "version",
                      "config", "device", "onboardingcodes", "dns",
                      "echo", "log", "rand"]


def get_shell_command(response):
    return [line.split()[0].strip() for line in response]


def parse_config_response(response):
    config = {}
    for param in response:
        param_name = param.split(":")[0].lower()
        if "discriminator" in param_name:
            value = int(param.split(":")[1].strip(), 16)
        elif "pincode" in param_name:
            value = int(param.split(":")[1].strip())
        else:
            value = int(param.split(":")[1].split()[0].strip())

        if "hardwareversion" in param_name:
            param_name = "hardwarever"

        config[param_name] = value
    return config


def parse_boarding_codes_response(response):
    codes = {}
    for param in response:
        codes[param.split(":")[0].lower()] = param.split()[1].strip()
    return codes


@pytest.mark.smoketest
def test_smoke_test(device):
    ret = device.wait_for_output("Open IoT SDK shell example application start")
    assert ret != None and len(ret) > 0
    ret = device.wait_for_output("Open IoT SDK shell example application run")
    assert ret != None and len(ret) > 0


@pytest.mark.ctrltest
def test_command_check(device):
    try:
        chip.native.Init()
    except exceptions.ChipStackException as ex:
        log.error("CHIP initialization failed {}".format(ex))
        assert False
    except:
        log.error("CHIP initialization failed")
        assert False

    ret = device.wait_for_output("Open IoT SDK shell example application start")
    assert ret != None and len(ret) > 0
    ret = device.wait_for_output("Open IoT SDK shell example application run")
    assert ret != None and len(ret) > 0

    # Help
    ret = device.send(command="help", expected_output="Done")
    assert ret != None and len(ret) > 1
    shell_commands = get_shell_command(ret[1:-1])
    assert set(SHELL_COMMAND_NAME) == set(shell_commands)

    # Echo
    ret = device.send(command="echo Hello", expected_output="Done")
    assert ret != None and len(ret) > 1
    assert "Hello" in ret[-2]

    # Log
    ret = device.send(command="log Hello", expected_output="Done")
    assert ret != None and len(ret) > 1
    assert "[INF] [TOO] Hello" in ret[-2]

    # Rand
    ret = device.send(command="rand", expected_output="Done")
    assert ret != None and len(ret) > 1
    assert ret[-2].rstrip().isdigit()

    # Base64
    hex_string = "1234"
    ret = device.send(command="base64 encode {}".format(
        hex_string), expected_output="Done")
    assert ret != None and len(ret) > 1
    base64code = ret[-2]
    ret = device.send(command="base64 decode {}".format(
        base64code), expected_output="Done")
    assert ret != None and len(ret) > 1
    assert ret[-2].rstrip() == hex_string

    # Version
    ret = device.send(command="version", expected_output="Done")
    assert ret != None and len(ret) > 1
    assert "CHIP" in ret[-2].split()[0]
    app_version = ret[-2].split()[1]
    assert isinstance(version.parse(app_version), version.Version)

    # Config
    ret = device.send(command="config", expected_output="Done")
    assert ret != None and len(ret) > 2

    config = parse_config_response(ret[1:-1])

    for param_name, value in config.items():
        ret = device.send(command="config {}".format(
            param_name), expected_output="Done")
        assert ret != None and len(ret) > 1
        if "discriminator" in param_name:
            assert int(ret[-2].split()[0], 16) == value
        else:
            assert int(ret[-2].split()[0]) == value

    new_value = int(config['discriminator']) + 1
    ret = device.send(command="config discriminator {}".format(
        new_value), expected_output="Done")
    assert ret != None and len(ret) > 1
    assert "Setup discriminator set to: {}".format(new_value) in ret[-2]

    ret = device.send(command="config discriminator", expected_output="Done")
    assert ret != None and len(ret) > 1
    assert int(ret[-2].split()[0], 16) == new_value

    # Onboardingcodes
    ret = device.send(command="onboardingcodes none", expected_output="Done")
    assert ret != None and len(ret) > 2

    boarding_codes = parse_boarding_codes_response(ret[1:-1])

    for param, value in boarding_codes.items():
        ret = device.send(command="onboardingcodes none {}".format(
            param), expected_output="Done")
        assert ret != None and len(ret) > 1
        assert value == ret[-2].strip()

    try:
        device_details = dict(SetupPayload().ParseQrCode(
            "VP:vendorpayload%{}".format(boarding_codes['qrcode'])).attributes)
    except exceptions.ChipStackError as ex:
        log.error(ex.msg)
        assert False
    assert device_details != None and len(device_details) != 0

    try:
        device_details = dict(SetupPayload().ParseManualPairingCode(
            boarding_codes['manualpairingcode']).attributes)
    except exceptions.ChipStackError as ex:
        log.error(ex.msg)
        assert False
    assert device_details != None and len(device_details) != 0

    # Exit - should be the last check
    ret = device.send(command="exit", expected_output="Goodbye")
    assert ret != None and len(ret) > 0
