# SPDX-License-Identifier: Apache-2.0
# Copyright 2015 The Meson development team

from __future__ import annotations

import enum
import os
import re
import typing as T


from . import ExtensionModule, ModuleInfo
from . import ModuleReturnValue
from .. import mesonlib, build
from .. import mlog
from ..interpreter.type_checking import DEPEND_FILES_KW, DEPENDS_KW, INCLUDE_DIRECTORIES
from ..interpreterbase.decorators import ContainerTypeInfo, FeatureNew, KwargInfo, typed_kwargs, typed_pos_args
from ..mesonlib import MachineChoice, MesonException
from ..programs import ExternalProgram

if T.TYPE_CHECKING:
    from . import ModuleState
    from ..compilers.compilers import Language, Compiler
    from ..interpreter import Interpreter
    from ..programs import CommandList

    from typing_extensions import Literal, TypedDict

    class CompileResources(TypedDict):

        depend_files: T.List[mesonlib.FileOrString]
        depends: T.List[T.Union[build.BuildTarget, build.CustomTarget]]
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        implicit_include_directories: bool
        args: T.List[str]


class ResourceCompilerType(enum.Enum):
    windres = 1
    rc = 2
    wrc = 3

class WindowsModule(ExtensionModule):

    INFO = ModuleInfo('windows')

    def __init__(self, interpreter: 'Interpreter'):
        super().__init__(interpreter)
        self._rescomp: T.Optional[T.Tuple[ExternalProgram, ResourceCompilerType]] = None
        self.methods.update({
            'compile_resources': self.compile_resources,
        })

    def detect_compiler(self, compilers: T.Dict[Language, 'Compiler']) -> 'Compiler':
        # https://github.com/python/mypy/issues/18826
        # However, we need to support versions of mypy that cannot deduce the
        # tuple either.
        for l in T.cast('T.Tuple[Language, ...]', ('c', 'cpp')):
            if l in compilers:
                return compilers[l]
        raise MesonException('Resource compilation requires a C or C++ compiler.')

    def _find_resource_compiler(self, state: 'ModuleState') -> T.Tuple[ExternalProgram, ResourceCompilerType]:
        # FIXME: Does not handle `native: true` executables, see
        # See https://github.com/mesonbuild/meson/issues/1531
        # Take a parameter instead of the hardcoded definition below
        for_machine = MachineChoice.HOST

        if self._rescomp:
            return self._rescomp

        # Will try cross / native file and then env var
        rescomp = ExternalProgram.from_bin_list(state.environment, for_machine, 'windres')

        if not rescomp or not rescomp.found():
            def search_programs(names: T.List[str]) -> T.Optional[ExternalProgram]:
                for name in names:
                    program = ExternalProgram(name, silent=True)
                    if program.found():
                        return program
                return None

            comp = self.detect_compiler(state.environment.coredata.compilers[for_machine])
            if comp.linker and comp.linker.id in {'link', 'lld-link'}:
                rescomp = search_programs(['rc', 'llvm-rc'])
            else:
                rescomp = search_programs(['windres', 'llvm-windres'])

        if not rescomp:
            raise MesonException('Could not find Windows resource compiler')

        for (arg, match, rc_type) in [
                ('/?', '^.*Microsoft.*Resource Compiler.*$', ResourceCompilerType.rc),
                ('/?', 'LLVM Resource Converter.*$', ResourceCompilerType.rc),
                ('--version', '^.*GNU windres.*$', ResourceCompilerType.windres),
                ('--version', '^.*Wine Resource Compiler.*$', ResourceCompilerType.wrc),
        ]:
            p, o, e = mesonlib.Popen_safe(rescomp.get_command() + [arg])
            m = re.search(match, o, re.MULTILINE)
            if m:
                mlog.log('Windows resource compiler: %s' % m.group())
                self._rescomp = (rescomp, rc_type)
                break
        else:
            raise MesonException('Could not determine type of Windows resource compiler')

        return self._rescomp

    @typed_pos_args('windows.compile_resources', varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex), min_varargs=1)
    @typed_kwargs(
        'windows.compile_resources',
        DEPEND_FILES_KW.evolve(since='0.47.0'),
        DEPENDS_KW.evolve(since='0.47.0'),
        INCLUDE_DIRECTORIES,
        KwargInfo('implicit_include_directories', bool, default=False, since='1.11.0'),
        KwargInfo('args', ContainerTypeInfo(list, str), default=[], listify=True),
    )
    def compile_resources(self, state: 'ModuleState',
                          args: T.Tuple[T.List[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex]]],
                          kwargs: 'CompileResources') -> ModuleReturnValue:
        extra_args = kwargs['args'].copy()
        wrc_depend_files = state._interpreter.source_strings_to_files(kwargs['depend_files'])
        wrc_depends = kwargs['depends']
        for d in wrc_depends:
            if isinstance(d, build.CustomTarget):
                extra_args += state.get_include_args([
                    build.IncludeDirs('', [], False, state.current_build_project,
                                      [self.interpreter.backend.get_target_dir(d)])
                ])
        extra_args += state.get_include_args(kwargs['include_directories'], kwargs['implicit_include_directories'])

        rescomp, rescomp_type = self._find_resource_compiler(state)
        if rescomp_type == ResourceCompilerType.rc:
            # RC is used to generate .res files, a special binary resource
            # format, which can be passed directly to LINK (apparently LINK uses
            # CVTRES internally to convert this to a COFF object)
            suffix = 'res'
            res_args = extra_args + ['/nologo', '/fo@OUTPUT@', '@INPUT@']
        elif rescomp_type == ResourceCompilerType.windres:
            # ld only supports object files, so windres is used to generate a
            # COFF object
            suffix = 'o'
            res_args = extra_args + ['@INPUT@', '@OUTPUT@']

            m = 'Argument {!r} has a space which may not work with windres due to ' \
                'a MinGW bug: https://sourceware.org/bugzilla/show_bug.cgi?id=4933'
            for arg in extra_args:
                if ' ' in arg:
                    mlog.warning(m.format(arg), fatal=False)
        else:
            suffix = 'o'
            res_args = extra_args + ['@INPUT@', '-o', '@OUTPUT@']

        res_targets: T.List[build.CustomTarget] = []

        def get_names() -> T.Iterable[T.Tuple[str, str, T.Union[mesonlib.File, build.CustomTargetIndex]]]:
            for src in args[0]:
                if isinstance(src, str):
                    yield os.path.join(state.subdir, src), src, mesonlib.File.from_source_file(state.environment.source_dir, state.subdir, src)
                elif isinstance(src, mesonlib.File):
                    yield src.relative_name(), src.fname, src
                elif isinstance(src, build.CustomTargetIndex):
                    FeatureNew.single_use('windows.compile_resource CustomTargetIndex in positional arguments', '0.61.0',
                                          state.subproject, location=state.current_node)
                    # This dance avoids a case where two indexes of the same
                    # target are given as separate arguments.
                    yield (f'{src.get_id()}_{src.target.get_outputs().index(src.output)}',
                           f'windows_compile_resources_{src.get_filename()}', src)
                else:
                    if len(src.get_outputs()) > 1:
                        FeatureNew.single_use('windows.compile_resource CustomTarget with multiple outputs in positional arguments',
                                              '0.61.0', state.subproject, location=state.current_node)
                    for i, out in enumerate(src.get_outputs()):
                        # Chances are that src.get_filename() is already the name of that
                        # target, add a prefix to avoid name clash.
                        yield f'{src.get_id()}_{i}', f'windows_compile_resources_{i}_{out}', src[i]

        for name, name_formatted, src in get_names():
            # Path separators are not allowed in target names
            name = name.replace('/', '_').replace('\\', '_').replace(':', '_')
            name_formatted = name_formatted.replace('/', '_').replace('\\', '_').replace(':', '_')
            output = f'{name}_@BASENAME@.{suffix}'
            depfile: T.Optional[str] = None
            depfile_type: T.Optional[Literal['gcc', 'msvc']] = None
            command: CommandList = []

            if rescomp_type == ResourceCompilerType.rc:
                compiler = self.detect_compiler(state.environment.coredata.compilers[MachineChoice.HOST])
                command.extend(state.environment.get_build_command())
                command.extend(['--internal', 'rc',
                                '--rc', *rescomp.get_command(),
                                '--cl', *compiler.get_exelist(False)])

                if compiler.id in {'msvc', 'clang-cl', 'intel-cl'}:
                    depfile_type = 'msvc'
                    command.extend(['--Xarg=/showIncludes',
                                    '--Xarg=/EP',
                                    '--Xarg=/nologo',
                                    '--Xarg=/DRC_INVOKED',
                                    '--Xarg=/Tc@INPUT@',
                                    ])
                else:
                    depfile = f'{output}.d'
                    depfile_type = 'gcc'
                    command.extend(['--Xarg=-xc',
                                    '--Xarg=-E',
                                    '--Xarg=-MD',
                                    '--Xarg=-MQ@OUTPUT@',
                                    '--Xarg=-MF@DEPFILE@',
                                    '--Xarg=-DRC_INVOKED',
                                    ])
            else:
                command.extend(rescomp.get_command())

            command.extend(res_args)

            # instruct binutils windres to generate a preprocessor depfile
            if rescomp_type == ResourceCompilerType.windres:
                depfile = f'{output}.d'
                depfile_type = 'gcc'
                command.extend(['--preprocessor-arg=-MD',
                                '--preprocessor-arg=-MQ@OUTPUT@',
                                '--preprocessor-arg=-MF@DEPFILE@'])

            res_targets.append(build.CustomTarget(
                name_formatted,
                state.subdir,
                state.environment,
                command,
                [src],
                [output],
                state.current_build_project,
                depfile=depfile,
                depfile_type=depfile_type,
                depend_files=wrc_depend_files,
                extra_depends=wrc_depends,
                description='Compiling Windows resource {}',
            ))

        return ModuleReturnValue(res_targets, [res_targets])

def initialize(interp: 'Interpreter') -> WindowsModule:
    return WindowsModule(interp)
