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

from __future__ import annotations

from pathlib import Path

from .base import ExternalDependency, DependencyException, sort_libpaths, DependencyTypeName
from ..mesonlib import EnvironmentVariables, OptionKey, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged, MachineChoice, join_args
from ..programs import find_external_program, ExternalProgram
from .. import mlog
from pathlib import PurePath
from functools import lru_cache
import re
import os
import shlex
import typing as T

if T.TYPE_CHECKING:
    from typing_extensions import Literal
    from .._typing import ImmutableListProtocol

    from ..environment import Environment
    from ..utils.core import EnvironOrDict
    from ..interpreter.type_checking import PkgConfigDefineType

class PkgConfigInterface:
    '''Base class wrapping a pkg-config implementation'''

    class_impl: PerMachine[T.Union[Literal[False], T.Optional[PkgConfigInterface]]] = PerMachine(False, False)
    class_cli_impl: PerMachine[T.Union[Literal[False], T.Optional[PkgConfigCLI]]] = PerMachine(False, False)

    @staticmethod
    def instance(env: Environment, for_machine: MachineChoice, silent: bool) -> T.Optional[PkgConfigInterface]:
        '''Return a pkg-config implementation singleton'''
        for_machine = for_machine if env.is_cross_build() else MachineChoice.HOST
        impl = PkgConfigInterface.class_impl[for_machine]
        if impl is False:
            impl = PkgConfigCLI(env, for_machine, silent)
            if not impl.found():
                impl = None
            if not impl and not silent:
                mlog.log('Found pkg-config:', mlog.red('NO'))
            PkgConfigInterface.class_impl[for_machine] = impl
        return impl

    @staticmethod
    def _cli(env: Environment, for_machine: MachineChoice, silent: bool = False) -> T.Optional[PkgConfigCLI]:
        '''Return the CLI pkg-config implementation singleton
        Even when we use another implementation internally, external tools might
        still need the CLI implementation.
        '''
        for_machine = for_machine if env.is_cross_build() else MachineChoice.HOST
        impl: T.Union[Literal[False], T.Optional[PkgConfigInterface]] # Help confused mypy
        impl = PkgConfigInterface.instance(env, for_machine, silent)
        if impl and not isinstance(impl, PkgConfigCLI):
            impl = PkgConfigInterface.class_cli_impl[for_machine]
            if impl is False:
                impl = PkgConfigCLI(env, for_machine, silent)
                if not impl.found():
                    impl = None
                PkgConfigInterface.class_cli_impl[for_machine] = impl
        return T.cast('T.Optional[PkgConfigCLI]', impl) # Trust me, mypy

    @staticmethod
    def get_env(env: Environment, for_machine: MachineChoice, uninstalled: bool = False) -> EnvironmentVariables:
        cli = PkgConfigInterface._cli(env, for_machine)
        return cli._get_env(uninstalled) if cli else EnvironmentVariables()

    @staticmethod
    def setup_env(environ: EnvironOrDict, env: Environment, for_machine: MachineChoice,
                  uninstalled: bool = False) -> EnvironOrDict:
        cli = PkgConfigInterface._cli(env, for_machine)
        return cli._setup_env(environ, uninstalled) if cli else environ

    def __init__(self, env: Environment, for_machine: MachineChoice) -> None:
        self.env = env
        self.for_machine = for_machine

    def found(self) -> bool:
        '''Return whether pkg-config is supported'''
        raise NotImplementedError

    def version(self, name: str) -> T.Optional[str]:
        '''Return module version or None if not found'''
        raise NotImplementedError

    def cflags(self, name: str, allow_system: bool = False,
               define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        '''Return module cflags
           @allow_system: If False, remove default system include paths
        '''
        raise NotImplementedError

    def libs(self, name: str, static: bool = False, allow_system: bool = False,
             define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        '''Return module libs
           @static: If True, also include private libraries
           @allow_system: If False, remove default system libraries search paths
        '''
        raise NotImplementedError

    def variable(self, name: str, variable_name: str,
                 define_variable: PkgConfigDefineType) -> T.Optional[str]:
        '''Return module variable or None if variable is not defined'''
        raise NotImplementedError

    def list_all(self) -> ImmutableListProtocol[str]:
        '''Return all available pkg-config modules'''
        raise NotImplementedError

class PkgConfigCLI(PkgConfigInterface):
    '''pkg-config CLI implementation'''

    def __init__(self, env: Environment, for_machine: MachineChoice, silent: bool) -> None:
        super().__init__(env, for_machine)
        self._detect_pkgbin()
        if self.pkgbin and not silent:
            mlog.log('Found pkg-config:', mlog.green('YES'), mlog.bold(f'({self.pkgbin.get_path()})'), mlog.blue(self.pkgbin_version))

    def found(self) -> bool:
        return bool(self.pkgbin)

    @lru_cache(maxsize=None)
    def version(self, name: str) -> T.Optional[str]:
        mlog.debug(f'Determining dependency {name!r} with pkg-config executable {self.pkgbin.get_path()!r}')
        ret, version, _ = self._call_pkgbin(['--modversion', name])
        return version if ret == 0 else None

    @staticmethod
    def _define_variable_args(define_variable: PkgConfigDefineType) -> T.List[str]:
        ret = []
        if define_variable:
            for pair in define_variable:
                ret.append('--define-variable=' + '='.join(pair))
        return ret

    @lru_cache(maxsize=None)
    def cflags(self, name: str, allow_system: bool = False,
               define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        env = None
        if allow_system:
            env = os.environ.copy()
            env['PKG_CONFIG_ALLOW_SYSTEM_CFLAGS'] = '1'
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        args += ['--cflags', name]
        ret, out, err = self._call_pkgbin(args, env=env)
        if ret != 0:
            raise DependencyException(f'Could not generate cflags for {name}:\n{err}\n')
        return self._split_args(out)

    @lru_cache(maxsize=None)
    def libs(self, name: str, static: bool = False, allow_system: bool = False,
             define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        env = None
        if allow_system:
            env = os.environ.copy()
            env['PKG_CONFIG_ALLOW_SYSTEM_LIBS'] = '1'
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        if static:
            args.append('--static')
        args += ['--libs', name]
        ret, out, err = self._call_pkgbin(args, env=env)
        if ret != 0:
            raise DependencyException(f'Could not generate libs for {name}:\n{err}\n')
        return self._split_args(out)

    @lru_cache(maxsize=None)
    def variable(self, name: str, variable_name: str,
                 define_variable: PkgConfigDefineType) -> T.Optional[str]:
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        args += ['--variable=' + variable_name, name]
        ret, out, err = self._call_pkgbin(args)
        if ret != 0:
            raise DependencyException(f'Could not get variable for {name}:\n{err}\n')
        variable = out.strip()
        # pkg-config doesn't distinguish between empty and nonexistent variables
        # use the variable list to check for variable existence
        if not variable:
            ret, out, _ = self._call_pkgbin(['--print-variables', name])
            if not re.search(rf'^{variable_name}$', out, re.MULTILINE):
                return None
        mlog.debug(f'Got pkg-config variable {variable_name} : {variable}')
        return variable

    @lru_cache(maxsize=None)
    def list_all(self) -> ImmutableListProtocol[str]:
        ret, out, err = self._call_pkgbin(['--list-all'])
        if ret != 0:
            raise DependencyException(f'could not list modules:\n{err}\n')
        return [i.split(' ', 1)[0] for i in out.splitlines()]

    @staticmethod
    def _split_args(cmd: str) -> T.List[str]:
        # pkg-config paths follow Unix conventions, even on Windows; split the
        # output using shlex.split rather than mesonlib.split_args
        return shlex.split(cmd)

    def _detect_pkgbin(self) -> None:
        for potential_pkgbin in find_external_program(
                self.env, self.for_machine, 'pkg-config', 'Pkg-config',
                self.env.default_pkgconfig, allow_default_for_cross=False):
            version_if_ok = self._check_pkgconfig(potential_pkgbin)
            if version_if_ok:
                self.pkgbin = potential_pkgbin
                self.pkgbin_version = version_if_ok
                return
        self.pkgbin = None

    def _check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]:
        if not pkgbin.found():
            mlog.log(f'Did not find pkg-config by name {pkgbin.name!r}')
            return None
        command_as_string = ' '.join(pkgbin.get_command())
        try:
            helptext = Popen_safe(pkgbin.get_command() + ['--help'])[1]
            if 'Pure-Perl' in helptext:
                mlog.log(f'Found pkg-config {command_as_string!r} but it is Strawberry Perl and thus broken. Ignoring...')
                return None
            p, out = Popen_safe(pkgbin.get_command() + ['--version'])[0:2]
            if p.returncode != 0:
                mlog.warning(f'Found pkg-config {command_as_string!r} but it failed when ran')
                return None
        except FileNotFoundError:
            mlog.warning(f'We thought we found pkg-config {command_as_string!r} but now it\'s not there. How odd!')
            return None
        except PermissionError:
            msg = f'Found pkg-config {command_as_string!r} but didn\'t have permissions to run it.'
            if not self.env.machines.build.is_windows():
                msg += '\n\nOn Unix-like systems this is often caused by scripts that are not executable.'
            mlog.warning(msg)
            return None
        return out.strip()

    def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables:
        env = EnvironmentVariables()
        key = OptionKey('pkg_config_path', machine=self.for_machine)
        extra_paths: T.List[str] = self.env.coredata.optstore.get_value(key)[:]
        if uninstalled:
            uninstalled_path = Path(self.env.get_build_dir(), 'meson-uninstalled').as_posix()
            if uninstalled_path not in extra_paths:
                extra_paths.append(uninstalled_path)
        env.set('PKG_CONFIG_PATH', extra_paths)
        sysroot = self.env.properties[self.for_machine].get_sys_root()
        if sysroot:
            env.set('PKG_CONFIG_SYSROOT_DIR', [sysroot])
        pkg_config_libdir_prop = self.env.properties[self.for_machine].get_pkg_config_libdir()
        if pkg_config_libdir_prop:
            env.set('PKG_CONFIG_LIBDIR', pkg_config_libdir_prop)
        env.set('PKG_CONFIG', [join_args(self.pkgbin.get_command())])
        return env

    def _setup_env(self, env: EnvironOrDict, uninstalled: bool = False) -> T.Dict[str, str]:
        envvars = self._get_env(uninstalled)
        env = envvars.get_env(env)
        # Dump all PKG_CONFIG environment variables
        for key, value in env.items():
            if key.startswith('PKG_'):
                mlog.debug(f'env[{key}]: {value}')
        return env

    def _call_pkgbin(self, args: T.List[str], env: T.Optional[EnvironOrDict] = None) -> T.Tuple[int, str, str]:
        assert isinstance(self.pkgbin, ExternalProgram)
        env = env or os.environ
        env = self._setup_env(env)
        cmd = self.pkgbin.get_command() + args
        p, out, err = Popen_safe_logged(cmd, env=env)
        return p.returncode, out.strip(), err.strip()


class PkgConfigDependency(ExternalDependency):

    def __init__(self, name: str, environment: Environment, kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
        super().__init__(DependencyTypeName('pkgconfig'), environment, kwargs, language=language)
        self.name = name
        self.is_libtool = False
        pkgconfig = PkgConfigInterface.instance(self.env, self.for_machine, self.silent)
        if not pkgconfig:
            msg = f'Pkg-config for machine {self.for_machine} not found. Giving up.'
            if self.required:
                raise DependencyException(msg)
            mlog.debug(msg)
            return
        self.pkgconfig = pkgconfig

        version = self.pkgconfig.version(name)
        if version is None:
            return

        self.version = version
        self.is_found = True

        try:
            # Fetch cargs to be used while using this dependency
            self._set_cargs()
            # Fetch the libraries and library paths needed for using this
            self._set_libs()
        except DependencyException as e:
            mlog.debug(f"Pkg-config error with '{name}': {e}")
            if self.required:
                raise
            else:
                self.compile_args = []
                self.link_args = []
                self.is_found = False
                self.reason = e

    def __repr__(self) -> str:
        s = '<{0} {1}: {2} {3}>'
        return s.format(self.__class__.__name__, self.name, self.is_found,
                        self.version_reqs)

    def _convert_mingw_paths(self, args: ImmutableListProtocol[str]) -> T.List[str]:
        '''
        Both MSVC and native Python on Windows cannot handle MinGW-esque /c/foo
        paths so convert them to C:/foo. We cannot resolve other paths starting
        with / like /home/foo so leave them as-is so that the user gets an
        error/warning from the compiler/linker.
        '''
        if not self.env.machines.build.is_windows():
            return args.copy()
        converted = []
        for arg in args:
            pargs: T.Tuple[str, ...] = tuple()
            # Library search path
            if arg.startswith('-L/'):
                pargs = PurePath(arg[2:]).parts
                tmpl = '-L{}:/{}'
            elif arg.startswith('-I/'):
                pargs = PurePath(arg[2:]).parts
                tmpl = '-I{}:/{}'
            # Full path to library or .la file
            elif arg.startswith('/'):
                pargs = PurePath(arg).parts
                tmpl = '{}:/{}'
            elif arg.startswith(('-L', '-I')) or (len(arg) > 2 and arg[1] == ':'):
                # clean out improper '\\ ' as comes from some Windows pkg-config files
                arg = arg.replace('\\ ', ' ')
            if len(pargs) > 1 and len(pargs[1]) == 1:
                arg = tmpl.format(pargs[1], '/'.join(pargs[2:]))
            converted.append(arg)
        return converted

    def _set_cargs(self) -> None:
        allow_system = False
        if self.language == 'fortran':
            # gfortran doesn't appear to look in system paths for INCLUDE files,
            # so don't allow pkg-config to suppress -I flags for system paths
            allow_system = True
        cflags = self.pkgconfig.cflags(self.name, allow_system)
        self.compile_args = self._convert_mingw_paths(cflags)

    def _search_libs(self, libs_in: ImmutableListProtocol[str], raw_libs_in: ImmutableListProtocol[str]) -> T.Tuple[T.List[str], T.List[str]]:
        '''
        @libs_in: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @raw_libs_in: pkg-config --libs

        We always look for the file ourselves instead of depending on the
        compiler to find it with -lfoo or foo.lib (if possible) because:
        1. We want to be able to select static or shared
        2. We need the full path of the library to calculate RPATH values
        3. De-dup of libraries is easier when we have absolute paths

        Libraries that are provided by the toolchain or are not found by
        find_library() will be added with -L -l pairs.
        '''
        # Library paths should be safe to de-dup
        #
        # First, figure out what library paths to use. Originally, we were
        # doing this as part of the loop, but due to differences in the order
        # of -L values between pkg-config and pkgconf, we need to do that as
        # a separate step. See:
        # https://github.com/mesonbuild/meson/issues/3951
        # https://github.com/mesonbuild/meson/issues/4023
        #
        # Separate system and prefix paths, and ensure that prefix paths are
        # always searched first.
        prefix_libpaths: OrderedSet[str] = OrderedSet()
        # We also store this raw_link_args on the object later
        raw_link_args = self._convert_mingw_paths(raw_libs_in)
        for arg in raw_link_args:
            if arg.startswith('-L') and not arg.startswith(('-L-l', '-L-L')):
                path = arg[2:]
                if not os.path.isabs(path):
                    # Resolve the path as a compiler in the build directory would
                    path = os.path.join(self.env.get_build_dir(), path)
                prefix_libpaths.add(path)
        # Library paths are not always ordered in a meaningful way
        #
        # Instead of relying on pkg-config or pkgconf to provide -L flags in a
        # specific order, we reorder library paths ourselves, according to th
        # order specified in PKG_CONFIG_PATH. See:
        # https://github.com/mesonbuild/meson/issues/4271
        #
        # Only prefix_libpaths are reordered here because there should not be
        # too many system_libpaths to cause library version issues.
        pkg_config_path: T.List[str] = self.env.coredata.optstore.get_value(OptionKey('pkg_config_path', machine=self.for_machine))
        pkg_config_path = self._convert_mingw_paths(pkg_config_path)
        prefix_libpaths = OrderedSet(sort_libpaths(list(prefix_libpaths), pkg_config_path))
        system_libpaths: OrderedSet[str] = OrderedSet()
        full_args = self._convert_mingw_paths(libs_in)
        for arg in full_args:
            if arg.startswith(('-L-l', '-L-L')):
                # These are D language arguments, not library paths
                continue
            if arg.startswith('-L') and arg[2:] not in prefix_libpaths:
                system_libpaths.add(arg[2:])
        # Use this re-ordered path list for library resolution
        libpaths = list(prefix_libpaths) + list(system_libpaths)
        # Track -lfoo libraries to avoid duplicate work
        libs_found: OrderedSet[str] = OrderedSet()
        # Track not-found libraries to know whether to add library paths
        libs_notfound = []
        # Generate link arguments for this library
        link_args = []
        for lib in full_args:
            if lib.startswith(('-L-l', '-L-L')):
                # These are D language arguments, add them as-is
                pass
            elif lib.startswith('-L'):
                # We already handled library paths above
                continue
            elif lib.startswith('-l:'):
                # see: https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a
                # also : See the documentation of -lnamespec | --library=namespec in the linker manual
                #                     https://sourceware.org/binutils/docs-2.18/ld/Options.html

                # Don't resolve the same -l:libfoo.a argument again
                if lib in libs_found:
                    continue
                libfilename = lib[3:]
                foundname = None
                for libdir in libpaths:
                    target = os.path.join(libdir, libfilename)
                    if os.path.exists(target):
                        foundname = target
                        break
                if foundname is None:
                    if lib in libs_notfound:
                        continue
                    else:
                        mlog.warning('Library {!r} not found for dependency {!r}, may '
                                     'not be successfully linked'.format(libfilename, self.name))
                    libs_notfound.append(lib)
                else:
                    lib = foundname
            elif lib.startswith('-l'):
                # Don't resolve the same -lfoo argument again
                if lib in libs_found:
                    continue
                if self.clib_compiler:
                    args = self.clib_compiler.find_library(lib[2:], self.env,
                                                           libpaths, self.libtype,
                                                           lib_prefix_warning=False)
                # If the project only uses a non-clib language such as D, Rust,
                # C#, Python, etc, all we can do is limp along by adding the
                # arguments as-is and then adding the libpaths at the end.
                else:
                    args = None
                if args is not None:
                    libs_found.add(lib)
                    # Replace -l arg with full path to library if available
                    # else, library is either to be ignored, or is provided by
                    # the compiler, can't be resolved, and should be used as-is
                    if args:
                        if not args[0].startswith('-l'):
                            lib = args[0]
                    else:
                        continue
                else:
                    # Library wasn't found, maybe we're looking in the wrong
                    # places or the library will be provided with LDFLAGS or
                    # LIBRARY_PATH from the environment (on macOS), and many
                    # other edge cases that we can't account for.
                    #
                    # Add all -L paths and use it as -lfoo
                    if lib in libs_notfound:
                        continue
                    if self.static:
                        mlog.warning('Static library {!r} not found for dependency {!r}, may '
                                     'not be statically linked'.format(lib[2:], self.name))
                    libs_notfound.append(lib)
            elif lib.endswith(".la"):
                shared_libname = self.extract_libtool_shlib(lib)
                shared_lib = os.path.join(os.path.dirname(lib), shared_libname)
                if not os.path.exists(shared_lib):
                    shared_lib = os.path.join(os.path.dirname(lib), ".libs", shared_libname)

                if not os.path.exists(shared_lib):
                    raise DependencyException(f'Got a libtools specific "{lib}" dependencies'
                                              'but we could not compute the actual shared'
                                              'library path')
                self.is_libtool = True
                lib = shared_lib
                if lib in link_args:
                    continue
            link_args.append(lib)
        # Add all -Lbar args if we have -lfoo args in link_args
        if libs_notfound:
            # Order of -L flags doesn't matter with ld, but it might with other
            # linkers such as MSVC, so prepend them.
            link_args = ['-L' + lp for lp in prefix_libpaths] + link_args
        return link_args, raw_link_args

    def _set_libs(self) -> None:
        # Force pkg-config to output -L fields even if they are system
        # paths so we can do manual searching with cc.find_library() later.
        libs = self.pkgconfig.libs(self.name, self.static, allow_system=True)
        # Also get the 'raw' output without -Lfoo system paths for adding -L
        # args with -lfoo when a library can't be found, and also in
        # gnome.generate_gir + gnome.gtkdoc which need -L -l arguments.
        raw_libs = self.pkgconfig.libs(self.name, self.static, allow_system=False)
        self.link_args, self.raw_link_args = self._search_libs(libs, raw_libs)

    def extract_field(self, la_file: str, fieldname: str) -> T.Optional[str]:
        with open(la_file, encoding='utf-8') as f:
            for line in f:
                arr = line.strip().split('=')
                if arr[0] == fieldname:
                    return arr[1][1:-1]
        return None

    def extract_dlname_field(self, la_file: str) -> T.Optional[str]:
        return self.extract_field(la_file, 'dlname')

    def extract_libdir_field(self, la_file: str) -> T.Optional[str]:
        return self.extract_field(la_file, 'libdir')

    def extract_libtool_shlib(self, la_file: str) -> T.Optional[str]:
        '''
        Returns the path to the shared library
        corresponding to this .la file
        '''
        dlname = self.extract_dlname_field(la_file)
        if dlname is None:
            return None

        # Darwin uses absolute paths where possible; since the libtool files never
        # contain absolute paths, use the libdir field
        if self.env.machines[self.for_machine].is_darwin():
            dlbasename = os.path.basename(dlname)
            libdir = self.extract_libdir_field(la_file)
            if libdir is None:
                return dlbasename
            return os.path.join(libdir, dlbasename)
        # From the comments in extract_libtool(), older libtools had
        # a path rather than the raw dlname
        return os.path.basename(dlname)

    @staticmethod
    def log_tried() -> str:
        return 'pkgconfig'

    def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None,
                     configtool: T.Optional[str] = None, internal: T.Optional[str] = None,
                     default_value: T.Optional[str] = None,
                     pkgconfig_define: PkgConfigDefineType = None) -> str:
        if pkgconfig:
            try:
                variable = self.pkgconfig.variable(self.name, pkgconfig, pkgconfig_define)
                if variable is not None:
                    return variable
            except DependencyException:
                pass
        if default_value is not None:
            return default_value
        raise DependencyException(f'Could not get pkg-config variable and no default provided for {self!r}')
