# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2018 The Meson development team
# Copyright © 2024-2025 Intel Corporation

# This file contains the detection logic for external dependencies.
# Custom logic for several other packages are in separate files.

from __future__ import annotations
import copy
import dataclasses
import os
import collections
import itertools
import typing as T
import uuid
from enum import Enum

from .. import mlog, mesonlib
from ..compilers import clib_langs
from ..mesonlib import LibType, MachineChoice, MesonException, HoldableObject, version_compare_many
from ..options import OptionKey
#from ..interpreterbase import FeatureDeprecated, FeatureNew

if T.TYPE_CHECKING:
    from typing_extensions import Literal, Required, Self, TypedDict, TypeAlias

    from ..compilers.compilers import Language, Compiler
    from ..environment import Environment
    from ..interpreterbase import FeatureCheckBase
    from ..build import (
        CustomTarget, IncludeDirs, CustomTargetIndex, LinkableTargetTypes,
        StaticLibrary, ExtractedObjects, TargetSources
    )
    from ..interpreter.type_checking import PkgConfigDefineType

    IncludeType: TypeAlias = Literal['system', 'non-system', 'preserve']

    class DependencyObjectKWs(TypedDict, total=False):

        """Keyword arguments that the Dependency IR object accepts.

        This is different than the arguments as taken by the Interpreter, since
        it is expected to be clean.
        """

        cmake_args: T.List[str]
        cmake_module_path: T.List[str]
        cmake_package_version: str
        components: T.List[str]
        include_type: IncludeType
        language: T.Optional[Language]
        main: bool
        method: DependencyMethods
        modules: T.List[str]
        native: Required[MachineChoice]
        optional_modules: T.List[str]
        private_headers: bool
        required: bool
        static: T.Optional[bool]
        version: T.List[str]

        # Only in the python dependency
        embed: bool

        # Only passed internally, not part of the DSL API
        paths: T.List[str]
        returncode_value: int
        silent: bool
        tools: T.List[str]
        version_arg: str
        build_config: str

    _MissingCompilerBase = Compiler
else:
    _MissingCompilerBase = object


DepType = T.TypeVar('DepType', bound='ExternalDependency', covariant=True)

class DependencyException(MesonException):
    '''Exceptions raised while trying to find dependencies'''


class MissingCompiler(_MissingCompilerBase):
    """Represent a None Compiler - when no tool chain is found.
    replacing AttributeError with DependencyException"""

    # These are needed in type checking mode to avoid errors, but we don't want
    # the extra overhead at runtime
    if T.TYPE_CHECKING:
        def __init__(self) -> None:
            pass

        def get_optimization_args(self, optimization_level: str) -> T.List[str]:
            return []

        def get_output_args(self, outputname: str) -> T.List[str]:
            return []

        def _sanity_check_source_code(self) -> str:
            return ''

    def __getattr__(self, item: str) -> T.Any:
        if item.startswith('__'):
            raise AttributeError()
        raise DependencyException('no toolchain found')

    def __bool__(self) -> bool:
        return False


class DependencyMethods(Enum):
    # Auto means to use whatever dependency checking mechanisms in whatever order meson thinks is best.
    AUTO = 'auto'
    PKGCONFIG = 'pkg-config'
    CMAKE = 'cmake'
    # The dependency is provided by the standard library and does not need to be linked
    BUILTIN = 'builtin'
    # Just specify the standard link arguments, assuming the operating system provides the library.
    SYSTEM = 'system'
    # This is only supported on OSX - search the frameworks directory by name.
    EXTRAFRAMEWORK = 'extraframework'
    # Detect using the sysconfig module.
    SYSCONFIG = 'sysconfig'
    # Specify using a "program"-config style tool
    CONFIG_TOOL = 'config-tool'
    # Misc
    DUB = 'dub'


DependencyTypeName = T.NewType('DependencyTypeName', str)


class Dependency(HoldableObject):

    type_name: DependencyTypeName

    def __init__(self, kwargs: DependencyObjectKWs) -> None:
        # This allows two Dependencies to be compared even after being copied.
        # The purpose is to allow the name to be changed, but still have a proper comparison
        self._id = uuid.uuid4().int
        self.name = f'dep{self._id}'
        self.version:  T.Optional[str] = None
        self.language: T.Optional[Language] = kwargs.get('language') # None means C-like
        self.is_found = False
        self.compile_args: T.List[str] = []
        self.link_args:    T.List[str] = []
        # Raw -L and -l arguments without manual library searching
        # If None, self.link_args will be used
        self.raw_link_args: T.Optional[T.List[str]] = None
        self.sources: T.List[TargetSources] = []
        self.extra_files: T.List[mesonlib.File] = []
        self.include_type = kwargs.get('include_type', 'preserve')
        self.ext_deps: T.List[Dependency] = []
        self.d_features: T.DefaultDict[str, T.List[T.Any]] = collections.defaultdict(list)
        self.featurechecks: T.List['FeatureCheckBase'] = []
        self.feature_since: T.Optional[T.Tuple[str, str]] = None
        self.meson_variables: T.List[str] = []

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Dependency):
            return NotImplemented
        return self._id == other._id

    def __hash__(self) -> int:
        return self._id

    def __repr__(self) -> str:
        return f'<{self.__class__.__name__} {self.name}: {self.is_found}>'

    def is_built(self) -> bool:
        return False

    def is_named(self) -> bool:
        if self.name is None:
            return False
        return self.name != f'dep{self._id}'

    def summary_value(self) -> T.Union[str, mlog.AnsiDecorator, mlog.AnsiText]:
        if not self.found():
            return mlog.red('NO')
        if not self.version:
            return mlog.green('YES')
        return mlog.AnsiText(mlog.green('YES'), ' ', mlog.cyan(self.version))

    def get_compile_args(self) -> T.List[str]:
        if self.include_type == 'system':
            converted = []
            for i in self.compile_args:
                if i.startswith('-I') or i.startswith('/I'):
                    converted += ['-isystem' + i[2:]]
                else:
                    converted += [i]
            return converted
        if self.include_type == 'non-system':
            converted = []
            for i in self.compile_args:
                if i.startswith('-isystem'):
                    converted += ['-I' + i[8:]]
                else:
                    converted += [i]
            return converted
        return self.compile_args

    def get_all_compile_args(self) -> T.List[str]:
        """Get the compile arguments from this dependency and its sub dependencies."""
        return list(itertools.chain(self.get_compile_args(),
                                    *(d.get_all_compile_args() for d in self.ext_deps)))

    def get_link_args(self, language: T.Optional[Language] = None, raw: bool = False) -> T.List[str]:
        if raw and self.raw_link_args is not None:
            return self.raw_link_args
        return self.link_args

    def get_all_link_args(self) -> T.List[str]:
        """Get the link arguments from this dependency and its sub dependencies."""
        return list(itertools.chain(self.get_link_args(),
                                    *(d.get_all_link_args() for d in self.ext_deps)))

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

    def get_sources(self) -> T.List[TargetSources]:
        """Source files that need to be added to the target.
        As an example, gtest-all.cc when using GTest."""
        return self.sources

    def get_extra_files(self) -> T.List[mesonlib.File]:
        """Mostly for introspection and IDEs"""
        return self.extra_files

    def get_name(self) -> str:
        return self.name

    def get_version(self) -> str:
        if self.version:
            return self.version
        else:
            return 'unknown'

    def get_include_dirs(self) -> T.List['IncludeDirs']:
        return []

    def get_include_type(self) -> str:
        return self.include_type

    def get_exe_args(self, compiler: 'Compiler') -> T.List[str]:
        return []

    def get_partial_dependency(self, *, compile_args: bool = False,
                               link_args: bool = False, links: bool = False,
                               includes: bool = False, sources: bool = False) -> 'Dependency':
        """Create a new dependency that contains part of the parent dependency.

        The following options can be inherited:
            links -- all link_with arguments
            includes -- all include_directory and -I/-isystem calls
            sources -- any source, header, or generated sources
            compile_args -- any compile args
            link_args -- any link args

        Additionally the new dependency will have the version parameter of its
        parent (if any) and the requested values of any dependencies will be
        added as well.
        """
        raise RuntimeError('Unreachable code in partial_dependency called')

    def _add_sub_dependency(self, deplist: T.Iterable[T.Callable[[], 'Dependency']]) -> bool:
        """Add an internal dependency from a list of possible dependencies.

        This method is intended to make it easier to add additional
        dependencies to another dependency internally.

        Returns true if the dependency was successfully added, false
        otherwise.
        """
        for d in deplist:
            dep = d()
            if dep.is_found:
                self.ext_deps.append(dep)
                return True
        return False

    def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None,
                     configtool: T.Optional[str] = None, internal: T.Optional[str] = None,
                     system: T.Optional[str] = None, default_value: T.Optional[str] = None,
                     pkgconfig_define: PkgConfigDefineType = None) -> str:
        if default_value is not None:
            return default_value
        raise DependencyException(f'No default provided for dependency {self!r}, which is not pkg-config, cmake, or config-tool based.')

    def generate_system_dependency(self, include_type: IncludeType) -> 'Dependency':
        new_dep = copy.deepcopy(self)
        new_dep.include_type = include_type
        return new_dep

    def get_as_static(self, recursive: bool) -> Dependency:
        """Used as base case for internal_dependency"""
        return self

    def get_as_shared(self, recursive: bool) -> Dependency:
        """Used as base case for internal_dependency"""
        return self

class InternalDependency(Dependency):

    type_name = DependencyTypeName('internal')

    def __init__(self, version: str, incdirs: T.Optional[T.List['IncludeDirs']] = None,
                 compile_args: T.Optional[T.List[str]] = None,
                 link_args: T.Optional[T.List[str]] = None,
                 libraries: T.Optional[T.List[LinkableTargetTypes]] = None,
                 whole_libraries: T.Optional[T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]]] = None,
                 sources: T.Optional[T.Sequence[TargetSources]] = None,
                 extra_files: T.Optional[T.Sequence[mesonlib.File]] = None,
                 ext_deps: T.Optional[T.List[Dependency]] = None, variables: T.Optional[T.Dict[str, str]] = None,
                 d_module_versions: T.Optional[T.List[T.Union[str, int]]] = None,
                 d_import_dirs: T.Optional[T.List['IncludeDirs']] = None,
                 objects: T.Optional[T.List['ExtractedObjects']] = None,
                 name: T.Optional[str] = None):
        super().__init__({'native': MachineChoice.HOST})  # TODO: does the native key actually matter
        self.version = version
        self.is_found = True
        self.include_directories = incdirs or []
        self.compile_args = compile_args or []
        self.link_args = link_args or []
        self.libraries = libraries or []
        self.whole_libraries = whole_libraries or []
        self.sources = list(sources or [])
        self.extra_files = list(extra_files or [])
        self.ext_deps = ext_deps or []
        self.variables = variables or {}
        self.objects = objects or []
        if d_module_versions:
            self.d_features['versions'] = d_module_versions
        if d_import_dirs:
            self.d_features['import_dirs'] = d_import_dirs
        if name:
            self.name = name

    def __deepcopy__(self, memo: T.Dict[int, 'InternalDependency']) -> 'InternalDependency':
        result = self.__class__.__new__(self.__class__)
        assert isinstance(result, InternalDependency)
        memo[id(self)] = result
        for k, v in self.__dict__.items():
            if k in {'libraries', 'whole_libraries'}:
                setattr(result, k, copy.copy(v))
            else:
                setattr(result, k, copy.deepcopy(v, memo))
        return result

    def summary_value(self) -> mlog.AnsiDecorator:
        # Omit the version.  Most of the time it will be just the project
        # version, which is uninteresting in the summary.
        return mlog.green('YES')

    def is_built(self) -> bool:
        if self.sources or self.libraries or self.whole_libraries:
            return True
        return any(d.is_built() for d in self.ext_deps)

    def get_partial_dependency(self, *, compile_args: bool = False,
                               link_args: bool = False, links: bool = False,
                               includes: bool = False, sources: bool = False,
                               extra_files: bool = False) -> Self:
        final_compile_args = self.compile_args.copy() if compile_args else []
        final_link_args = self.link_args.copy() if link_args else []
        final_libraries = self.libraries.copy() if links else []
        final_whole_libraries = self.whole_libraries.copy() if links else []
        final_sources = self.sources.copy() if sources else []
        final_extra_files = self.extra_files.copy() if extra_files else []
        final_includes = self.include_directories.copy() if includes else []
        final_deps = [d.get_partial_dependency(
            compile_args=compile_args, link_args=link_args, links=links,
            includes=includes, sources=sources) for d in self.ext_deps]
        return type(self)(
            self.version, final_includes, final_compile_args,
            final_link_args, final_libraries, final_whole_libraries,
            final_sources, final_extra_files, final_deps, self.variables, [], [], [], self.name)

    def get_include_dirs(self) -> T.List['IncludeDirs']:
        return self.include_directories

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

    def generate_link_whole_dependency(self) -> Dependency:
        from ..build import SharedLibrary, CustomTarget, CustomTargetIndex
        new_dep = copy.deepcopy(self)
        for x in new_dep.libraries:
            if isinstance(x, SharedLibrary):
                raise MesonException('Cannot convert a dependency to link_whole when it contains a '
                                     'SharedLibrary')
            elif isinstance(x, (CustomTarget, CustomTargetIndex)) and x.links_dynamically():
                raise MesonException('Cannot convert a dependency to link_whole when it contains a '
                                     'CustomTarget or CustomTargetIndex which is a shared library')

        # Mypy doesn't understand that the above is a TypeGuard
        new_dep.whole_libraries += T.cast('T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]]',
                                          new_dep.libraries)
        new_dep.libraries = []
        return new_dep

    def get_as_static(self, recursive: bool) -> InternalDependency:
        new_dep = copy.copy(self)
        new_dep.libraries = [lib.get('static', recursive) for lib in self.libraries]
        if recursive:
            new_dep.ext_deps = [dep.get_as_static(True) for dep in self.ext_deps]
        return new_dep

    def get_as_shared(self, recursive: bool) -> InternalDependency:
        new_dep = copy.copy(self)
        new_dep.libraries = [lib.get('shared', recursive) for lib in self.libraries]
        if recursive:
            new_dep.ext_deps = [dep.get_as_shared(True) for dep in self.ext_deps]
        return new_dep

class ExternalDependency(Dependency):
    def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
        Dependency.__init__(self, kwargs)
        self.env = environment
        self.name = name
        self.is_found = False
        self.version_reqs = kwargs.get('version', [])
        self.required = kwargs.get('required', True)
        self.silent = kwargs.get('silent', False)
        static = kwargs.get('static')
        if static is None:
            static = T.cast('bool', self.env.coredata.optstore.get_value_for(OptionKey('prefer_static')))
        self.static = static
        self.libtype = LibType.STATIC if self.static else LibType.PREFER_SHARED
        # Is this dependency to be run on the build platform?
        self.for_machine = kwargs['native']
        self.clib_compiler = detect_compiler(self.name, environment, self.for_machine, self.language)

    def get_compiler(self) -> T.Union['MissingCompiler', 'Compiler']:
        return self.clib_compiler

    def get_partial_dependency(self, *, compile_args: bool = False,
                               link_args: bool = False, links: bool = False,
                               includes: bool = False, sources: bool = False) -> Dependency:
        new = copy.copy(self)
        new._id = uuid.uuid4().int
        if not compile_args:
            new.compile_args = []
        if not link_args:
            new.link_args = []
        if not sources:
            new.sources = []
        if not includes:
            pass # TODO maybe filter compile_args?
        if not sources:
            new.sources = []

        return new

    def log_details(self) -> str:
        return ''

    def log_info(self) -> str:
        return ''

    # Check if dependency version meets the requirements
    def _check_version(self) -> None:
        if not self.is_found:
            return

        if self.version_reqs:
            for_msg = ['for', mlog.bold(self.for_machine.get_lower_case_name()), 'machine']

            # an unknown version can never satisfy any requirement
            if not self.version:
                self.is_found = False
                found_msg: mlog.TV_LoggableList = []
                found_msg.extend(['Dependency', mlog.bold(self.name)])
                found_msg.extend(for_msg)
                found_msg.append('found:')
                found_msg.extend([str(mlog.red('NO')) + '.', 'Unknown version, but need:', self.version_reqs])
                mlog.log(*found_msg)

                if self.required:
                    m = f'Unknown version, but need {self.version_reqs!r}.'
                    raise DependencyException(m)

            else:
                (self.is_found, not_found, found) = \
                    version_compare_many(self.version, self.version_reqs)
                if not self.is_found:
                    found_msg = ['Dependency', mlog.bold(self.name)]
                    found_msg.extend(for_msg)
                    found_msg.append('found:')
                    found_msg += [str(mlog.red('NO')) + '.',
                                  'Found', mlog.normal_cyan(self.version), 'but need:',
                                  mlog.bold(', '.join([f"'{e}'" for e in not_found]))]
                    if found:
                        found_msg += ['; matched:',
                                      ', '.join([f"'{e}'" for e in found])]
                    mlog.log(*found_msg)

                    if self.required:
                        m = 'Invalid version, need {!r} {!r} found {!r}.'
                        raise DependencyException(m.format(self.name, not_found, self.version))
                    return


class NotFoundDependency(Dependency):

    type_name = DependencyTypeName('not-found')

    def __init__(self, name: str, environment: 'Environment') -> None:
        super().__init__({'native': MachineChoice.HOST})  # TODO: does this actually matter?
        self.env = environment
        self.name = name
        self.is_found = False

    def get_partial_dependency(self, *, compile_args: bool = False,
                               link_args: bool = False, links: bool = False,
                               includes: bool = False, sources: bool = False) -> 'NotFoundDependency':
        new = copy.copy(self)
        new._id = uuid.uuid4().int
        return new


class ExternalLibrary(ExternalDependency):

    type_name = DependencyTypeName('library')

    def __init__(self, name: str, link_args: T.List[str], environment: 'Environment',
                 language: Language, for_machine: MachineChoice, silent: bool = False) -> None:
        super().__init__(name, environment, {'language': language, 'native': for_machine})
        self.is_found = False
        if link_args:
            self.is_found = True
            self.link_args = link_args
        if not silent:
            if self.is_found:
                mlog.log('Library', mlog.bold(name), 'found:', mlog.green('YES'))
            else:
                mlog.log('Library', mlog.bold(name), 'found:', mlog.red('NO'))

    def get_link_args(self, language: T.Optional[Language] = None, raw: bool = False) -> T.List[str]:
        '''
        External libraries detected using a compiler must only be used with
        compatible code. For instance, Vala libraries (.vapi files) cannot be
        used with C code, and not all Rust library types can be linked with
        C-like code. Note that C++ libraries *can* be linked with C code with
        a C++ linker (and vice-versa).
        '''
        # Using a vala library in a non-vala target, or a non-vala library in a vala target
        # XXX: This should be extended to other non-C linkers such as Rust
        if (self.language == 'vala' and language != 'vala') or \
           (language == 'vala' and self.language != 'vala'):
            return []
        return super().get_link_args(language=language, raw=raw)

    def get_partial_dependency(self, *, compile_args: bool = False,
                               link_args: bool = False, links: bool = False,
                               includes: bool = False, sources: bool = False) -> 'ExternalLibrary':
        # External library only has link_args, so ignore the rest of the
        # interface.
        new = copy.copy(self)
        new._id = uuid.uuid4().int
        if not link_args:
            new.link_args = []
        return new


def get_leaf_external_dependencies(deps: T.List[Dependency]) -> T.List[Dependency]:
    if not deps:
        # Ensure that we always return a new instance
        return deps.copy()
    final_deps = []
    while deps:
        next_deps = []
        for d in mesonlib.listify(deps):
            if not isinstance(d, Dependency) or d.is_built():
                raise DependencyException('Dependencies must be external dependencies')
            final_deps.append(d)
            next_deps.extend(d.ext_deps)
        deps = next_deps
    return final_deps


def sort_libpaths(libpaths: T.List[str], refpaths: T.List[str]) -> T.List[str]:
    """Sort <libpaths> according to <refpaths>

    It is intended to be used to sort -L flags returned by pkg-config.
    Pkg-config returns flags in random order which cannot be relied on.
    """
    if len(refpaths) == 0:
        return list(libpaths)

    def key_func(libpath: str) -> T.Tuple[int, int]:
        common_lengths: T.List[int] = []
        for refpath in refpaths:
            try:
                common_path: str = os.path.commonpath([libpath, refpath])
            except ValueError:
                common_path = ''
            common_lengths.append(len(common_path))
        max_length = max(common_lengths)
        max_index = common_lengths.index(max_length)
        reversed_max_length = len(refpaths[max_index]) - max_length
        return (max_index, reversed_max_length)
    return sorted(libpaths, key=key_func)

def strip_system_libdirs(environment: 'Environment', for_machine: MachineChoice, link_args: T.List[str]) -> T.List[str]:
    """Remove -L<system path> arguments.

    leaving these in will break builds where a user has a version of a library
    in the system path, and a different version not in the system path if they
    want to link against the non-system path version.
    """
    exclude = {f'-L{p}' for p in environment.get_compiler_system_lib_dirs(for_machine)}
    return [l for l in link_args if l not in exclude]

def strip_system_includedirs(environment: 'Environment', for_machine: MachineChoice, include_args: T.List[str]) -> T.List[str]:
    """Remove -I<system path> arguments.

    leaving these in will break builds where user want dependencies with system
    include-type used in rust.bindgen targets as if will cause system headers
    to not be found.
    """

    exclude = {f'-I{p}' for p in environment.get_compiler_system_include_dirs(for_machine)}
    return [i for i in include_args if i not in exclude]

def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: DependencyObjectKWs) -> T.List[DependencyMethods]:
    method = kwargs.get('method', DependencyMethods.AUTO)

    # Set the detection method. If the method is set to auto, use any available method.
    # If method is set to a specific string, allow only that detection method.
    if method == DependencyMethods.AUTO:
        # annotated for https://github.com/python/mypy/issues/19894
        methods: T.List[DependencyMethods] = list(possible)
    elif method in possible:
        methods = [method]
    else:
        raise DependencyException(
            'Unsupported detection method: {}, allowed methods are {}'.format(
                method.value,
                mlog.format_list([x.value for x in [DependencyMethods.AUTO] + list(possible)])))

    return methods

def detect_compiler(name: str, env: 'Environment', for_machine: MachineChoice,
                    language: T.Optional[Language]) -> T.Union['MissingCompiler', 'Compiler']:
    """Given a language and environment find the compiler used."""
    compilers = env.coredata.compilers[for_machine]

    # Set the compiler for this dependency if a language is specified,
    # else try to pick something that looks usable.
    if language:
        if language not in compilers:
            m = name.capitalize() + ' requires a {0} compiler, but ' \
                '{0} is not in the list of project languages'
            raise DependencyException(m.format(language.capitalize()))
        return compilers[language]
    else:
        # https://github.com/python/mypy/issues/18826
        # However, we need to support versions of mypy that cannot deduce the
        # tuple.
        for lang in T.cast('T.Tuple[Language, ...]', clib_langs):
            try:
                return compilers[lang]
            except KeyError:
                continue
    return MissingCompiler()


class SystemDependency(ExternalDependency):

    """Dependency base for System type dependencies."""

    type_name = DependencyTypeName('system')


class BuiltinDependency(ExternalDependency):

    """Dependency base for Builtin type dependencies."""

    type_name = DependencyTypeName('builtin')


@dataclasses.dataclass
class DependencyCandidate(T.Generic[DepType]):

    callable: T.Union[T.Type[DepType], T.Callable[[str, Environment, DependencyObjectKWs], DepType]]
    name: str
    method: str
    modules: T.Optional[T.List[str]] = None
    arguments: T.Optional[T.Tuple[Environment, DependencyObjectKWs]] = dataclasses.field(default=None)

    def __call__(self) -> DepType:
        if self.arguments is None:
            raise mesonlib.MesonBugException('Attempted to instantiate a candidate before setting its arguments')
        env, kwargs = self.arguments
        if self.modules is not None:
            kwargs['modules'] = self.modules.copy()
        return self.callable(self.name, env, kwargs)

    @classmethod
    def from_dependency(cls, name: str, dep: T.Type[DepType],
                        args: T.Optional[T.Tuple[Environment, DependencyObjectKWs]] = None,
                        modules: T.Optional[T.List[str]] = None,
                        ) -> DependencyCandidate[DepType]:
        tried = str(dep.type_name)

        # fixup the cases where type_name and log tried don't match
        if tried in {'extraframeworks', 'appleframeworks'}:
            tried = 'framework'
        elif tried == 'pkgconfig':
            tried = 'pkg-config'

        return cls(dep, name, tried, modules, arguments=args)
