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

from __future__ import annotations

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)

    # 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']
    elif isinstance(comp_class.LINKER_PREFIX, 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

    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)

    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)
    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)
    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]:
        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)
    # 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)
    # 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)
    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))
    else:
        __failed_to_detect_linker(compiler, check_args, o, e)
    return linker
