# 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 ..dependencies import Dependency
    from ..interpreter import Interpreter
    from ..programs import CommandList, Program
    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', stabilized='1.8.0')

    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[Program] = 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.environment,
                [self.scanner_bin, f'{scope}-code', '@INPUT@', '@OUTPUT@'],
                [xml_file],
                [f'{name}-protocol.c'],
                state.current_build_project,
                backend=state.backend,
            )
            targets.append(code)

            for side in sides:
                command: CommandList = [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.environment,
                    command,
                    [xml_file],
                    [f'{name}-{side}-protocol.h'],
                    state.current_build_project,
                    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)
