#!/usr/bin/env -S python3 -B
# Copyright (c) 2023 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 relative_importer  # isort: split # noqa: F401

import json
import sys
import traceback
from dataclasses import dataclass

import click
from matter_yamltests.errors import TestStepError, TestStepKeyError
from matter_yamltests.hooks import TestParserHooks, TestRunnerHooks, WebSocketRunnerHooks
from matter_yamltests.parser import TestStep


def _strikethrough(str):
    return '\u0336'.join(str[i:i+1] for i in range(0, len(str), 1))


_SUCCESS = click.style(u'\N{check mark}', fg='green')
_FAILURE = click.style(u'\N{ballot x}', fg='red')
_WARNING = click.style(u'\N{warning sign}', fg='yellow')


class TestColoredLogPrinter():
    def __init__(self, log_format='[{module}] {message}'):
        self.__log_format = log_format
        self.__log_styles = {
            'Info': 'green',
            'Error': 'bright_red',
            'Debug': 'blue',
            'Others': 'white'
        }

    def print(self, logs):
        for log in logs:
            fg = self.__log_styles[log.level]
            click.secho(self.__log_format.format(module=log.module, message=log.message), fg=fg)


@dataclass
class ParserStrings:
    start = 'Parsing {count} files.'
    stop = '{state} Parsing finished in {duration}ms with {successes} success and {errors} errors.'
    test_start = click.style('\t\tParsing: ', fg='white') + '{name}'
    test_result = '\r{state} ' + click.style('{duration}ms', fg='white')
    error_header = click.style('\t\tError at step {index}:', fg='white', bold=True)
    error_line = click.style('\t\t{error_line}', fg='white')


class TestParserLogger(TestParserHooks):
    def __init__(self):
        self.__success = 0
        self.__errors = 0
        self.__strings = ParserStrings()

    def parsing_start(self, count: int):
        print(self.__strings.start.format(count=count))

    def parsing_stop(self, duration: int):
        state = _FAILURE if self.__errors else _SUCCESS
        success = click.style(self.__success, bold=True)
        errors = click.style(self.__errors, bold=True)
        print(self.__strings.stop.format(state=state, successes=success, errors=errors, duration=duration))

    def test_parsing_start(self, name: str):
        print(self.__strings.test_start.format(name=name), end='')

    def test_parsing_failure(self, exception: Exception, duration: int):
        print(self.__strings.test_result.format(state=_FAILURE, duration=duration))

        try:
            raise exception
        except TestStepError:
            self.__print_step_exception(exception)
        else:
            traceback.print_exc()

        self.__errors += 1

    def test_parsing_success(self, duration: int):
        print(self.__strings.test_result.format(state=_SUCCESS, duration=duration))
        self.__success += 1

    def __print_step_exception(self, exception: TestStepError):
        if exception.context is None:
            return

        print('')
        print(self.__strings.error_header.format(index=exception.step_index))
        for line in exception.context.split('\n'):
            if '__error_start__' in line and '__error_end__' in line:
                before_end, after_end = line.split('__error_end__')
                before_start, after_start = before_end.split('__error_start__')
                line = click.style(before_start, fg='white')
                line += click.style(after_start, fg='red', bold=True)
                line += click.style(after_end, fg='white')
                line += click.style(f' <-- {exception}', bold=True)

            print(self.__strings.error_line.format(error_line=line))


@dataclass
class RunnerStrings:
    start = ''
    stop = 'Run finished in {duration}ms with {runned} steps runned and {skipped} steps skipped.'
    test_start = 'Running: "{name}" with {count} steps.'
    test_stop = '{state} Test finished in {duration}ms with {successes} success, {errors} errors and {warnings} warnings'
    step_skipped = click.style('\t\t{index}. ' + _strikethrough('Running ') + '{name}', fg='white')
    step_start = click.style('\t\t{index}. Running ', fg='white') + '{name}'
    step_unknown = ''
    step_result = '\r{state} ' + click.style('{duration}ms', fg='white')
    result_entry = click.style('\t\t  {state} [{category} check] {message}', fg='white')
    result_log = '\t\t    [{module}] {message}'
    result_failure = '\t\t    {key}: {value}'
    error_header = click.style('\t\t    Error at step {index}:', fg='white', bold=True)
    error_line = click.style('\t\t    {error_line}', fg='white')

    test_harness_test_start = '\t\t***** Test Start : {filename}'
    test_harness_test_stop_success = '\t\t***** Test Complete: {filename}'
    test_harness_step_skipped = '\t\t**** Skipping: {expression} == false'
    test_harness_step_start = '\t\t***** Test Step {index} : {name}'
    test_harness_step_failure = '\t\t***** Test Failure : {message}'
    test_harness_setup_device_connection_success = '\t\t**** Test Setup: Device Connected'
    test_harness_setup_device_connection_failure = '\t\t**** Test Setup: Device Connection Failure [deviceId={deviceId}. Error {message}]'
    log = '\t\t{message}'
    user_prompt = '\t\tUSER_PROMPT: {message}'


class TestRunnerLogger(TestRunnerHooks):
    def __init__(self, show_adapter_logs: bool = False, show_adapter_logs_on_error: bool = True, use_test_harness_log_format: bool = False):
        self.__show_adapter_logs = show_adapter_logs
        self.__show_adapter_logs_on_error = show_adapter_logs_on_error
        self.__use_test_harness_log_format = use_test_harness_log_format
        self.__filename = None
        self.__index = 1
        self.__successes = 0
        self.__warnings = 0
        self.__errors = 0
        self.__runned = 0
        self.__skipped = 0
        self.__strings = RunnerStrings()
        self.__log_printer = TestColoredLogPrinter(self.__strings.result_log)

    def start(self, count: int):
        print(self.__strings.start)

    def stop(self, duration: int):
        print(self.__strings.stop.format(runned=self.__runned, skipped=self.__skipped, duration=duration))

    def test_start(self, filename: str, name: str, count: int, steps: list[str] = []):
        print(self.__strings.test_start.format(name=click.style(name, bold=True), count=click.style(count, bold=True)))

        if self.__use_test_harness_log_format:
            self.__filename = filename
            print(self.__strings.test_harness_test_start.format(filename=filename))

    def test_stop(self, duration: int):
        if self.__errors:
            state = _FAILURE
        elif self.__warnings:
            state = _WARNING
        else:
            state = _SUCCESS

        if self.__use_test_harness_log_format and (state == _SUCCESS or state == _WARNING):
            print(self.__strings.test_harness_test_stop_success.format(filename=self.__filename))

        successes = click.style(self.__successes, bold=True)
        errors = click.style(self.__errors, bold=True)
        warnings = click.style(self.__warnings, bold=True)
        print(self.__strings.test_stop.format(state=state, successes=successes, errors=errors, warnings=warnings, duration=duration))

    def step_skipped(self, name: str, expression: str):
        print(self.__strings.step_skipped.format(index=self.__index, name=_strikethrough(name)))

        if self.__use_test_harness_log_format:
            print(self.__strings.test_harness_step_start.format(index=self.__index, name=name))
            print(self.__strings.test_harness_step_skipped.format(expression=expression))

        self.__index += 1
        self.__skipped += 1

    def step_start(self, request: TestStep):
        if self.__use_test_harness_log_format:
            print(self.__strings.test_harness_step_start.format(index=self.__index, name=request.label))

        print(self.__strings.step_start.format(index=self.__index, name=click.style(request.label, bold=True)), end='')
        # This is to keep previous behavior of UserPrompt. Where it logs USER_PROMPT prior to user input. See link below:
        # https://github.com/project-chip/connectedhomeip/blob/6644a4b0b0d1272ae325c651b27bd0e7068f3a8a/src/app/tests/suites/commands/log/LogCommands.cpp#L31
        if request.command == 'UserPrompt':
            message = request.arguments['values'][0]['value']
            print("\n" + self.__strings.user_prompt.format(message=f'{message}'))
        # flushing stdout such that the previous print statement is visible on the screen for long running tasks.
        sys.stdout.flush()

        self.__index += 1

    def step_unknown(self):
        print(self.__strings.step_unknown)

        self.__runned += 1

    def step_success(self, logger, logs, duration: int, request: TestStep):
        print(self.__strings.step_result.format(state=_SUCCESS, duration=duration))

        self.__print_results(logger)
        if self.__use_test_harness_log_format:
            if request.command == 'WaitForCommissionee':
                print(self.__strings.test_harness_setup_device_connection_success)
            elif request.command == 'Log':
                message = request.arguments['values'][0]['value']
                print(self.__strings.log.format(message=f'{message}'))

        if self.__show_adapter_logs:
            self.__log_printer.print(logs)

        self.__successes += logger.successes
        self.__warnings += logger.warnings
        self.__errors += logger.errors
        self.__runned += 1

    def step_failure(self, logger, logs, duration: int, request: TestStep, received):
        print(self.__strings.step_result.format(state=_FAILURE, duration=duration))

        self.__print_results(logger)

        if self.__show_adapter_logs or self.__show_adapter_logs_on_error:
            self.__log_printer.print(logs)

        has_failures_without_exception = False
        for entry in logger.entries:
            if entry.is_error() and entry.exception:
                try:
                    raise entry.exception
                except TestStepError as e:
                    self.__print_step_exception(e)
                else:
                    traceback.print_exc()
            elif entry.is_error():
                has_failures_without_exception = True

        if has_failures_without_exception:
            self.__print_failure(request.responses, received)

        self.__successes += logger.successes
        self.__warnings += logger.warnings
        self.__errors += logger.errors
        self.__runned += 1

        if self.__use_test_harness_log_format:
            message = ''
            for entry in logger.entries:
                if entry.is_error():
                    message = entry.message
                    print(self.__strings.test_harness_step_failure.format(message=message))
                    break

            if request.command == 'WaitForCommissionee':
                print(self.__strings.test_harness_setup_device_connection_failure.format(deviceId=request.node_id, message=message))

    def __print_step_exception(self, exception: TestStepError):
        if exception.context is None:
            return

        print('')
        print(self.__strings.error_header.format(index=exception.step_index))
        for line in exception.context.split('\n'):
            if '__error_start__' in line and '__error_end__' in line:
                before_end, after_end = line.split('__error_end__')
                before_start, after_start = before_end.split('__error_start__')
                line = click.style(before_start, fg='white')
                line += click.style(after_start, fg='red', bold=True)
                line += click.style(after_end, fg='white')
                line += click.style(f' <-- {exception}', bold=True)

            print(self.__strings.error_line.format(error_line=line))

    def __print_results(self, logger):
        for entry in logger.entries:
            if entry.is_warning():
                state = _WARNING
            elif entry.is_error():
                state = _FAILURE
            else:
                state = ' '  # Do not mark success to not make the output hard to read

            print(self.__strings.result_entry.format(state=state, category=entry.category, message=entry.message))

    def __print_failure(self, expected_response, received_response):
        expected_response = self.__prepare_data_for_printing(expected_response)
        expected_value = json.dumps(
            expected_response, sort_keys=True, indent=2, separators=(',', ': '))
        expected_value = expected_value.replace('\n', '\n\t\t              ')

        received_response = self.__prepare_data_for_printing(
            received_response)
        received_value = json.dumps(
            received_response, sort_keys=True, indent=2, separators=(',', ': '))
        received_value = received_value.replace('\n', '\n\t\t               ')
        print(self.__strings.result_failure.format(key=click.style("Expected", bold=True), value=expected_value))
        print(self.__strings.result_failure.format(key=click.style("Received", bold=True), value=received_value))

    def __prepare_data_for_printing(self, data):
        if isinstance(data, bytes):
            return data.decode('unicode_escape')
        elif isinstance(data, list):
            return [self.__prepare_data_for_printing(entry) for entry in data]
        elif isinstance(data, dict):
            result = {}
            for key, value in data.items():
                result[key] = self.__prepare_data_for_printing(value)
            return result

        return data


@dataclass
class WebSocketRunnerStrings:
    connecting = click.style('\t\tConnecting: ' + click.style('{url}', bold=True), fg='white')
    abort = 'Connecting to {url} failed.'
    success = click.style(f'\r{_SUCCESS} {{duration}}ms', fg='white')
    failure = click.style(f'\r{_WARNING} {{duration}}ms', fg='white')
    retry = click.style('\t\t  Retrying in {interval} seconds.', fg='white')


class WebSocketRunnerLogger(WebSocketRunnerHooks):
    def __init__(self):
        self.__strings = WebSocketRunnerStrings()

    def connecting(self, url: str):
        print(self.__strings.connecting.format(url=url), end='')
        sys.stdout.flush()

    def abort(self, url: str):
        print(self.__strings.abort.format(url=url))

    def success(self, duration: int):
        print(self.__strings.success.format(duration=duration))

    def failure(self, duration: int):
        print(self.__strings.failure.format(duration=duration))

    def retry(self, interval_between_retries_in_seconds: int):
        print(self.__strings.retry.format(interval=interval_between_retries_in_seconds))


#
# Everything below this comment is for testing purposes only.
# It is here to quickly check the look and feel of the output
# that is produced via the different hooks.
#
@click.group()
def simulate():
    pass


@simulate.command()
def parser():
    """Simulate parsing tests."""
    parser_logger = TestParserLogger()

    test_step = {
        'label': 'This is a fake test step',
        'nodeId': 1,
        'cluster': 'TestStepCluster',
        'commandd': 'WrongCommandKey',
        'attribute': 'TestStepAttribute',
    }

    test_step

    parser_logger.start(99)
    parser_logger.test_start('test.yaml')
    parser_logger.test_success(10)
    parser_logger.test_start('test2.yaml')
    exception = TestStepKeyError(test_step, 'commandd')
    exception.update_context(test_step, 1)
    parser_logger.test_failure(exception, 200)
    parser_logger.stop(10 + 200)


@simulate.command()
def runner():
    """Simulate running tests."""
    runner_logger = TestRunnerLogger(use_test_harness_log_format=True)

    class TestLogger:
        def __init__(self, entries=[], successes=0, warnings=0, errors=0):
            self.entries = entries
            self.successes = successes
            self.warnings = warnings
            self.errors = errors

    class LogEntry:
        def __init__(self, message, module='CTL', level='Others'):
            self.message = message
            self.module = module
            self.level = level

    success_logger = TestLogger(successes=3)
    error_logger = TestLogger(errors=2)

    expected_response = {}
    received_response = {'error': 'UNSUPPORTED_COMMAND'}

    empty_logs = []
    other_logs = [
        LogEntry('This is a message without a category'),
        LogEntry('This is an info message', level='Info'),
        LogEntry('This is an error message', level='Error'),
        LogEntry('This is a debug message', level='Debug'),
    ]

    runner_logger.start(99)
    runner_logger.test_start('Test_File', 'A test with multiple steps', 23)
    runner_logger.step_start('First Step')
    runner_logger.step_success(success_logger, empty_logs, 1234)
    runner_logger.step_start('Second Step')
    runner_logger.step_failure(error_logger, other_logs, 4321, expected_response, received_response)
    runner_logger.step_skipped('Third Step', 'SHOULD_RUN')
    runner_logger.step_start('Fourth Step')
    runner_logger.step_unknown()
    runner_logger.test_stop(1234 + 4321)
    runner_logger.stop(123456)


@simulate.command()
def websocket_abort():
    """Simulate a websocket connection aborting."""
    websocket_runner_logger = WebSocketRunnerLogger()
    url = 'ws://localhost:9002'

    websocket_runner_logger.connecting(url)
    websocket_runner_logger.failure(30)
    websocket_runner_logger.retry(1)
    websocket_runner_logger.connecting(url)
    websocket_runner_logger.failure(30)
    websocket_runner_logger.abort(url)


@simulate.command()
def websocket_connected():
    """Simulate a websocket connection that successfuly connects."""
    websocket_runner_logger = WebSocketRunnerLogger()
    url = 'ws://localhost:9002'

    websocket_runner_logger.connecting(url)
    websocket_runner_logger.failure(30)
    websocket_runner_logger.retry(1)
    websocket_runner_logger.connecting(url)
    websocket_runner_logger.success(30)


if __name__ == '__main__':
    simulate()
