# SPDX-License-Identifier: Apache-2.0
# Copyright 2022 Mark Bolhuis <mark@bolhuis.dev>

from __future__ import annotations
import os
import typing as T

from . import ExtensionModule, ModuleReturnValue, ModuleInfo
from ..build import CustomTarget
from ..interpreter.type_checking import NoneType, in_set_validator
from ..interpreterbase import typed_pos_args, typed_kwargs, KwargInfo, FeatureNew
from ..mesonlib import File, MesonException

if T.TYPE_CHECKING:
    from typing_extensions import Literal, TypedDict

    from . import ModuleState
    from ..build import Executable
    from ..dependencies import Dependency
    from ..interpreter import Interpreter
    from ..programs import ExternalProgram
    from ..mesonlib import FileOrString

    class ScanXML(TypedDict):

        public: bool
        client: bool
        server: bool
        include_core_only: bool

    class FindProtocol(TypedDict):

        state: Literal['stable', 'staging', 'unstable']
        version: T.Optional[int]

class WaylandModule(ExtensionModule):

    INFO = ModuleInfo('wayland', '0.62.0', unstable=True)

    def __init__(self, interpreter: Interpreter) -> None:
        super().__init__(interpreter)

        self.protocols_dep: T.Optional[Dependency] = None
        self.pkgdatadir: T.Optional[str] = None
        self.scanner_bin: T.Optional[T.Union[ExternalProgram, Executable]] = None

        self.methods.update({
            'scan_xml': self.scan_xml,
            'find_protocol': self.find_protocol,
        })

    @typed_pos_args('wayland.scan_xml', varargs=(str, File), min_varargs=1)
    @typed_kwargs(
        'wayland.scan_xml',
        KwargInfo('public', bool, default=False),
        KwargInfo('client', bool, default=True),
        KwargInfo('server', bool, default=False),
        KwargInfo('include_core_only', bool, default=True, since='0.64.0'),
    )
    def scan_xml(self, state: ModuleState, args: T.Tuple[T.List[FileOrString]], kwargs: ScanXML) -> ModuleReturnValue:
        if self.scanner_bin is None:
            # wayland-scanner from BUILD machine must have same version as wayland
            # libraries from HOST machine.
            dep = state.dependency('wayland-client')
            self.scanner_bin = state.find_tool('wayland-scanner', 'wayland-scanner', 'wayland_scanner',
                                               wanted=dep.version)

        scope = 'public' if kwargs['public'] else 'private'
        # We have to cast because mypy can't deduce these are literals
        sides = [i for i in T.cast("T.List[Literal['client', 'server']]", ['client', 'server']) if kwargs[i]]
        if not sides:
            raise MesonException('At least one of client or server keyword argument must be set to true.')

        xml_files = self.interpreter.source_strings_to_files(args[0])
        targets: T.List[CustomTarget] = []
        for xml_file in xml_files:
            name = os.path.splitext(os.path.basename(xml_file.fname))[0]

            code = CustomTarget(
                f'{name}-protocol',
                state.subdir,
                state.subproject,
                state.environment,
                [self.scanner_bin, f'{scope}-code', '@INPUT@', '@OUTPUT@'],
                [xml_file],
                [f'{name}-protocol.c'],
                backend=state.backend,
            )
            targets.append(code)

            for side in sides:
                command = [self.scanner_bin, f'{side}-header', '@INPUT@', '@OUTPUT@']
                if kwargs['include_core_only']:
                    command.append('--include-core-only')

                header = CustomTarget(
                    f'{name}-{side}-protocol',
                    state.subdir,
                    state.subproject,
                    state.environment,
                    command,
                    [xml_file],
                    [f'{name}-{side}-protocol.h'],
                    backend=state.backend,
                )
                targets.append(header)

        return ModuleReturnValue(targets, targets)

    @typed_pos_args('wayland.find_protocol', str)
    @typed_kwargs(
        'wayland.find_protocol',
        KwargInfo('state', str, default='stable', validator=in_set_validator({'stable', 'staging', 'unstable'})),
        KwargInfo('version', (int, NoneType)),
    )
    def find_protocol(self, state: ModuleState, args: T.Tuple[str], kwargs: FindProtocol) -> File:
        base_name = args[0]
        xml_state = kwargs['state']
        version = kwargs['version']

        if xml_state != 'stable' and version is None:
            raise MesonException(f'{xml_state} protocols require a version number.')

        if xml_state == 'stable' and version is not None:
            FeatureNew.single_use('Version number in stable wayland protocol', '1.5.0', state.subproject, location=state.current_node)

        if self.protocols_dep is None:
            self.protocols_dep = state.dependency('wayland-protocols')

        if self.pkgdatadir is None:
            self.pkgdatadir = self.protocols_dep.get_variable(pkgconfig='pkgdatadir', internal='pkgdatadir')

        xml_name = base_name
        if xml_state == 'unstable':
            xml_name += '-unstable'
        if version is not None:
            xml_name += f'-v{version}'
        xml_name += '.xml'

        path = os.path.join(self.pkgdatadir, xml_state, base_name, xml_name)

        if not os.path.exists(path):
            raise MesonException(f'The file {path} does not exist.')

        return File.from_absolute_file(path)


def initialize(interpreter: Interpreter) -> WaylandModule:
    return WaylandModule(interpreter)
