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

from __future__ import annotations

from .base import RSPFileSyntax
from .. import mlog
from ..mesonlib import (
    EnvironmentException,
    Popen_safe, Popen_safe_logged, join_args, search_version
)

import re
import shlex
import typing as T

if T.TYPE_CHECKING:
    from .linkers import DynamicLinker, GnuDynamicLinker
    from ..environment import Environment
    from ..compilers import Compiler
    from ..mesonlib import MachineChoice

defaults: T.Dict[str, T.List[str]] = {}
defaults['static_linker'] = ['ar', 'gar']
defaults['vs_static_linker'] = ['lib']
defaults['clang_cl_static_linker'] = ['llvm-lib']
defaults['cuda_static_linker'] = ['nvlink']
defaults['gcc_static_linker'] = ['gcc-ar']
defaults['clang_static_linker'] = ['llvm-ar']

def __failed_to_detect_linker(compiler: T.List[str], args: T.List[str], stdout: str, stderr: str) -> 'T.NoReturn':
    msg = 'Unable to detect linker for compiler `{}`\nstdout: {}\nstderr: {}'.format(
        join_args(compiler + args), stdout, stderr)
    raise EnvironmentException(msg)


def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Type['Compiler'],
                     comp_version: str, for_machine: MachineChoice, *,
                     use_linker_prefix: bool = True, invoked_directly: bool = True,
                     extra_args: T.Optional[T.List[str]] = None) -> 'DynamicLinker':
    from . import linkers
    env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)

    if invoked_directly or comp_class.get_argument_syntax() == 'msvc':
        rsp_syntax = RSPFileSyntax.MSVC
    else:
        rsp_syntax = RSPFileSyntax.GCC

    # Explicitly pass logo here so that we can get the version of link.exe
    if not use_linker_prefix or comp_class.LINKER_PREFIX is None:
        check_args = ['/logo', '--version']
    elif isinstance(comp_class.LINKER_PREFIX, str):
        check_args = [comp_class.LINKER_PREFIX + '/logo', comp_class.LINKER_PREFIX + '--version']
    else: # list
        check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version']

    check_args += env.coredata.get_external_link_args(for_machine, comp_class.language)

    override: T.List[str] = []
    value = env.lookup_binary_entry(for_machine, comp_class.language + '_ld')
    if value is not None:
        override = comp_class.use_linker_args(value[0], comp_version)
        check_args += override
    elif 'lld-link' in compiler:
        override = comp_class.use_linker_args('lld-link', comp_version)
        check_args += override

    if extra_args is not None:
        check_args.extend(extra_args)

    p, o, _ = Popen_safe(compiler + check_args)
    if 'LLD' in o.split('\n', maxsplit=1)[0]:
        if 'compatible with GNU linkers' in o:
            return linkers.LLVMDynamicLinker(
                compiler, for_machine, comp_class.LINKER_PREFIX,
                override, version=search_version(o))
        elif not invoked_directly:
            return linkers.ClangClDynamicLinker(
                for_machine, override, exelist=compiler, prefix=comp_class.LINKER_PREFIX,
                version=search_version(o), direct=False, machine=None,
                rsp_syntax=rsp_syntax)

    if value is not None and invoked_directly:
        compiler = value
        # We've already handled the non-direct case above

    p, o, e = Popen_safe(compiler + check_args)
    if 'LLD' in o.split('\n', maxsplit=1)[0]:
        return linkers.ClangClDynamicLinker(
            for_machine, [],
            prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [],
            exelist=compiler, version=search_version(o), direct=invoked_directly,
            rsp_syntax=rsp_syntax)
    elif 'OPTLINK' in o:
        # Optlink's stdout *may* begin with a \r character.
        return linkers.OptlinkDynamicLinker(compiler, for_machine, version=search_version(o))
    elif o.startswith('Microsoft') or e.startswith('Microsoft'):
        out = o or e
        match = re.search(r'.*(X86|X64|ARM|ARM64).*', out)
        if match:
            target = str(match.group(1))
        else:
            target = 'x86'

        return linkers.MSVCDynamicLinker(
            for_machine, [], machine=target, exelist=compiler,
            prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [],
            version=search_version(out), direct=invoked_directly,
            rsp_syntax=rsp_syntax)
    elif 'GNU coreutils' in o:
        import shutil
        fullpath = shutil.which(compiler[0])
        raise EnvironmentException(
            f"Found GNU link.exe instead of MSVC link.exe in {fullpath}.\n"
            "This link.exe is not a linker.\n"
            "You may need to reorder entries to your %PATH% variable to resolve this.")
    __failed_to_detect_linker(compiler, check_args, o, e)

def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Type['Compiler'],
                     comp_version: str, for_machine: MachineChoice, *,
                     extra_args: T.Optional[T.List[str]] = None) -> 'DynamicLinker':
    """Helper for guessing what linker to use on Unix-Like OSes.

    :compiler: Invocation to use to get linker
    :comp_class: The Compiler Type (uninstantiated)
    :comp_version: The compiler version string
    :for_machine: which machine this linker targets
    :extra_args: Any additional arguments required (such as a source file)
    """
    from . import linkers
    env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
    extra_args = extra_args or []

    ldflags = env.coredata.get_external_link_args(for_machine, comp_class.language)
    extra_args += comp_class._unix_args_to_native(ldflags, env.machines[for_machine])

    if isinstance(comp_class.LINKER_PREFIX, str):
        check_args = [comp_class.LINKER_PREFIX + '--version'] + extra_args
    else:
        check_args = comp_class.LINKER_PREFIX + ['--version'] + extra_args

    override: T.List[str] = []
    value = env.lookup_binary_entry(for_machine, comp_class.language + '_ld')
    if value is not None:
        override = comp_class.use_linker_args(value[0], comp_version)
        check_args += override

    mlog.debug('-----')
    p, o, e = Popen_safe_logged(compiler + check_args, msg='Detecting linker via')

    v = search_version(o + e)
    linker: DynamicLinker
    if 'LLD' in o.split('\n', maxsplit=1)[0] or 'tiarmlnk' in e:
        if isinstance(comp_class.LINKER_PREFIX, str):
            cmd = compiler + override + [comp_class.LINKER_PREFIX + '-v'] + extra_args
        else:
            cmd = compiler + override + comp_class.LINKER_PREFIX + ['-v'] + extra_args
        _, newo, newerr = Popen_safe_logged(cmd, msg='Detecting LLD linker via')

        lld_cls: T.Type[DynamicLinker]
        if 'ld64.lld' in newerr:
            lld_cls = linkers.LLVMLD64DynamicLinker
        else:
            lld_cls = linkers.LLVMDynamicLinker

        linker = lld_cls(
            compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    elif 'Snapdragon' in e and 'LLVM' in e:
        linker = linkers.QualcommLLVMDynamicLinker(
            compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    elif e.startswith('lld-link: '):
        # The LLD MinGW frontend didn't respond to --version before version 9.0.0,
        # and produced an error message about failing to link (when no object
        # files were specified), instead of printing the version number.
        # Let's try to extract the linker invocation command to grab the version.

        _, o, e = Popen_safe(compiler + check_args + ['-v'])

        try:
            linker_cmd = re.match(r'.*\n(.*?)\nlld-link: ', e, re.DOTALL).group(1)
            linker_cmd = shlex.split(linker_cmd)[0]
        except (AttributeError, IndexError, ValueError):
            pass
        else:
            _, o, e = Popen_safe([linker_cmd, '--version'])
            v = search_version(o)

        linker = linkers.LLVMDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    elif 'GNU' in o or 'GNU' in e:
        gnu_cls: T.Type[GnuDynamicLinker]
        # this is always the only thing on stdout, except for swift
        # which may or may not redirect the linker stdout to stderr
        if o.startswith('GNU gold') or e.startswith('GNU gold'):
            gnu_cls = linkers.GnuGoldDynamicLinker
        elif o.startswith('mold') or e.startswith('mold'):
            gnu_cls = linkers.MoldDynamicLinker
        else:
            gnu_cls = linkers.GnuBFDDynamicLinker
        linker = gnu_cls(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    elif 'Solaris' in e or 'Solaris' in o:
        for line in (o+e).split('\n'):
            if 'ld: Software Generation Utilities' in line:
                v = line.split(':')[2].lstrip()
                break
        else:
            v = 'unknown version'
        linker = linkers.SolarisDynamicLinker(
            compiler, for_machine, comp_class.LINKER_PREFIX, override,
            version=v)
    elif 'ld: 0706-012 The -- flag is not recognized' in e:
        if isinstance(comp_class.LINKER_PREFIX, str):
            _, _, e = Popen_safe(compiler + [comp_class.LINKER_PREFIX + '-V'] + extra_args)
        else:
            _, _, e = Popen_safe(compiler + comp_class.LINKER_PREFIX + ['-V'] + extra_args)
        linker = linkers.AIXDynamicLinker(
            compiler, for_machine, comp_class.LINKER_PREFIX, override,
            version=search_version(e))
    elif o.startswith('zig ld'):
        linker = linkers.ZigCCDynamicLinker(
            compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    # detect xtools first, bug #10805
    elif 'xtools-' in o.split('\n', maxsplit=1)[0]:
        xtools = o.split(' ', maxsplit=1)[0]
        v = xtools.split('-', maxsplit=2)[1]
        linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    # detect linker on MacOS - must be after other platforms because the
    # "(use -v to see invocation)" will match clang on other platforms,
    # but the rest of the checks will fail and call __failed_to_detect_linker.
    # First might be apple clang, second is for real gcc, the third is icc.
    # Note that "ld: unknown option: " sometimes instead is "ld: unknown options:".
    elif e.endswith('(use -v to see invocation)\n') or 'macosx_version' in e or 'ld: unknown option' in e:
        if isinstance(comp_class.LINKER_PREFIX, str):
            cmd = compiler + [comp_class.LINKER_PREFIX + '-v'] + extra_args
        else:
            cmd = compiler + comp_class.LINKER_PREFIX + ['-v'] + extra_args
        _, newo, newerr = Popen_safe_logged(cmd, msg='Detecting Apple linker via')

        for line in newerr.split('\n'):
            if 'PROJECT:ld' in line or 'PROJECT:dyld' in line:
                v = line.split('-')[1]
                break
        else:
            __failed_to_detect_linker(compiler, check_args, o, e)
        linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
    else:
        __failed_to_detect_linker(compiler, check_args, o, e)
    return linker
