# Copyright NTESS. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: MIT

import argparse
from typing import TYPE_CHECKING
from typing import Any
from typing import Union

import yaml

from ... import config
from ...collect import Collector
from ...hookspec import hookimpl
from ...util.rich import colorize
from ...workspace import Workspace
from ..types import CanarySubcommand

if TYPE_CHECKING:
    from ...config.argparsing import Parser
    from ...generator import AbstractTestGenerator
    from ...testcase import TestCase
    from ...testspec import ResolvedSpec


@hookimpl
def canary_addcommand(parser: "Parser") -> None:
    parser.add_command(Describe())


class Describe(CanarySubcommand):
    name = "describe"
    description = "Print information about a test file, test case"

    def setup_parser(self, parser: "Parser") -> None:
        parser.add_argument(
            "-o",
            dest="on_options",
            default=None,
            metavar="option",
            action="append",
            help="Turn option(s) on, such as '-o dbg' or '-o intel'",
        )
        parser.add_argument("testspec", help="Test file or test case spec")

    def execute(self, args: argparse.Namespace) -> int:
        collector = Collector()
        config.pluginmanager.hook.canary_collectstart(collector=collector)
        for type in collector.types:
            if gen := type.factory(args.testspec):
                describe_generator(gen, on_options=args.on_options)
                return 0

        # could be a test case in the test session?
        workspace = Workspace.load()
        try:
            case_or_spec = workspace.find(case=args.testspec)
        except:
            case_or_spec = workspace.find(spec=args.testspec)
        describe_testcase(case_or_spec)
        return 0


def describe_generator(
    file: "AbstractTestGenerator",
    on_options: list[str] | None = None,
) -> None:
    description = file.describe(on_options=on_options)
    print(colorize(description.rstrip()))


def dump(data: dict[str, Any]) -> str:
    return yaml.dump(data, default_flow_style=False)


def describe_testcase(case: Union["TestCase", "ResolvedSpec"], indent: str = "") -> None:
    from pygments import highlight
    from pygments.formatters import (
        TerminalTrueColorFormatter as Formatter,  # ty: ignore[unresolved-import]
    )
    from pygments.lexers import get_lexer_by_name

    state = case.asdict()
    text = dump({"name": case.display_name(), **state})
    lexer = get_lexer_by_name("yaml")
    formatter = Formatter(bg="dark", style="monokai")
    formatted_text = highlight(text.strip(), lexer, formatter)
    print(formatted_text)
