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

from __future__ import annotations

import typing as T

from .. import mesonlib, mlog
from .. import build
from ..compilers import Compiler
from ..interpreter.type_checking import BT_SOURCES_KW, STATIC_LIB_KWS
from ..interpreterbase.decorators import KwargInfo, permittedKwargs, typed_pos_args, typed_kwargs

from . import ExtensionModule, ModuleInfo

if T.TYPE_CHECKING:
    from . import ModuleState
    from ..interpreter import Interpreter, kwargs as kwtypes
    from ..interpreter.type_checking import SourcesVarargsType

    class CheckKw(kwtypes.StaticLibrary):

        compiler: Compiler
        mmx: SourcesVarargsType
        sse: SourcesVarargsType
        sse2: SourcesVarargsType
        sse3: SourcesVarargsType
        ssse3: SourcesVarargsType
        sse41: SourcesVarargsType
        sse42: SourcesVarargsType
        avx: SourcesVarargsType
        avx2: SourcesVarargsType
        neon: SourcesVarargsType


# FIXME add Altivec and AVX512.
ISETS = (
    'mmx',
    'sse',
    'sse2',
    'sse3',
    'ssse3',
    'sse41',
    'sse42',
    'avx',
    'avx2',
    'neon',
)


class SimdModule(ExtensionModule):

    INFO = ModuleInfo('SIMD', '0.42.0', unstable=True)

    def __init__(self, interpreter: Interpreter):
        super().__init__(interpreter)
        self.methods.update({
            'check': self.check,
        })

    @typed_pos_args('simd.check', str)
    @typed_kwargs('simd.check',
                  KwargInfo('compiler', Compiler, required=True),
                  *[BT_SOURCES_KW.evolve(name=iset, default=None) for iset in ISETS],
                  *[a for a in STATIC_LIB_KWS if a.name != 'sources'],
                  allow_unknown=True) # Because we also accept STATIC_LIB_KWS, but build targets have not been completely ported to typed_pos_args/typed_kwargs.
    @permittedKwargs({'compiler', *ISETS, *build.known_stlib_kwargs}) # Also remove this, per above comment
    def check(self, state: ModuleState, args: T.Tuple[str], kwargs: CheckKw) -> T.List[T.Union[T.List[build.StaticLibrary], build.ConfigurationData]]:
        result: T.List[build.StaticLibrary] = []

        if 'sources' in kwargs:
            raise mesonlib.MesonException('SIMD module does not support the "sources" keyword')

        local_kwargs = set((*ISETS, 'compiler'))
        static_lib_kwargs = T.cast('kwtypes.StaticLibrary', {k: v for k, v in kwargs.items() if k not in local_kwargs})

        prefix = args[0]
        compiler = kwargs['compiler']
        conf = build.ConfigurationData()

        for iset in ISETS:
            sources = kwargs[iset]
            if sources is None:
                continue

            compile_args = compiler.get_instruction_set_args(iset)
            if compile_args is None:
                mlog.log(f'Compiler supports {iset}:', mlog.red('NO'))
                continue

            if not compiler.has_multi_arguments(compile_args, state.environment)[0]:
                mlog.log(f'Compiler supports {iset}:', mlog.red('NO'))
                continue
            mlog.log(f'Compiler supports {iset}:', mlog.green('YES'))
            conf.values['HAVE_' + iset.upper()] = ('1', f'Compiler supports {iset}.')

            libname = prefix + '_' + iset
            lib_kwargs = static_lib_kwargs.copy()
            lib_kwargs['sources'] = sources

            # Add compile args we derived above to those the user provided us
            langarg_key = compiler.get_language() + '_args'
            old_lang_args = mesonlib.extract_as_list(lib_kwargs, langarg_key)
            all_lang_args = old_lang_args + compile_args
            lib_kwargs[langarg_key] = all_lang_args

            lib = self.interpreter.build_target(state.current_node, (libname, []), lib_kwargs, build.StaticLibrary)

            result.append(lib)

        return [result, conf]

def initialize(interp: Interpreter) -> SimdModule:
    return SimdModule(interp)
