# SPDX-License-Identifier: Apache-2.0
# Copyright © 2022-2024 Intel Corporation

"""Interpreter for converting Cargo Toml definitions to Meson AST

There are some notable limits here. We don't even try to convert something with
a build.rs: there's so few limits on what Cargo allows a build.rs (basically
none), and no good way for us to convert them. In that case, an actual meson
port will be required.
"""

from __future__ import annotations
import dataclasses
import importlib
import json
import os
import shutil
import collections
import urllib.parse
import itertools
import typing as T

from . import builder, version, cfg
from ..mesonlib import MesonException, Popen_safe, MachineChoice
from .. import coredata, mlog
from ..wrap.wrap import PackageDefinition

if T.TYPE_CHECKING:
    from types import ModuleType

    from typing_extensions import Protocol, Self

    from . import manifest
    from .. import mparser
    from ..environment import Environment
    from ..interpreterbase import SubProject
    from ..compilers.rust import RustCompiler

    # Copied from typeshed. Blarg that they don't expose this
    class DataclassInstance(Protocol):
        __dataclass_fields__: T.ClassVar[dict[str, dataclasses.Field[T.Any]]]

    _UnknownKeysT = T.TypeVar('_UnknownKeysT', manifest.FixedPackage,
                              manifest.FixedDependency, manifest.FixedLibTarget,
                              manifest.FixedBuildTarget)


# tomllib is present in python 3.11, before that it is a pypi module called tomli,
# we try to import tomllib, then tomli,
# TODO: add a fallback to toml2json?
tomllib: T.Optional[ModuleType] = None
toml2json: T.Optional[str] = None
for t in ['tomllib', 'tomli']:
    try:
        tomllib = importlib.import_module(t)
        break
    except ImportError:
        pass
else:
    # TODO: it would be better to use an Executable here, which could be looked
    # up in the cross file or provided by a wrap. However, that will have to be
    # passed in externally, since we don't have (and I don't think we should),
    # have access to the `Environment` for that in this module.
    toml2json = shutil.which('toml2json')


_EXTRA_KEYS_WARNING = (
    "This may (unlikely) be an error in the cargo manifest, or may be a missing "
    "implementation in Meson. If this issue can be reproduced with the latest "
    "version of Meson, please help us by opening an issue at "
    "https://github.com/mesonbuild/meson/issues. Please include the crate and "
    "version that is generating this warning if possible."
)

class TomlImplementationMissing(MesonException):
    pass


def load_toml(filename: str) -> T.Dict[object, object]:
    if tomllib:
        with open(filename, 'rb') as f:
            raw = tomllib.load(f)
    else:
        if toml2json is None:
            raise TomlImplementationMissing('Could not find an implementation of tomllib, nor toml2json')

        p, out, err = Popen_safe([toml2json, filename])
        if p.returncode != 0:
            raise MesonException('toml2json failed to decode output\n', err)

        raw = json.loads(out)

    if not isinstance(raw, dict):
        raise MesonException("Cargo.toml isn't a dictionary? How did that happen?")

    return raw


def fixup_meson_varname(name: str) -> str:
    """Fixup a meson variable name

    :param name: The name to fix
    :return: the fixed name
    """
    return name.replace('-', '_')


# Pylance can figure out that these do not, in fact, overlap, but mypy can't
@T.overload
def _fixup_raw_mappings(d: manifest.BuildTarget) -> manifest.FixedBuildTarget: ...  # type: ignore

@T.overload
def _fixup_raw_mappings(d: manifest.LibTarget) -> manifest.FixedLibTarget: ...  # type: ignore

@T.overload
def _fixup_raw_mappings(d: manifest.Dependency) -> manifest.FixedDependency: ...

def _fixup_raw_mappings(d: T.Union[manifest.BuildTarget, manifest.LibTarget, manifest.Dependency]
                        ) -> T.Union[manifest.FixedBuildTarget, manifest.FixedLibTarget,
                                     manifest.FixedDependency]:
    """Fixup raw cargo mappings to ones more suitable for python to consume.

    This does the following:
    * replaces any `-` with `_`, cargo likes the former, but python dicts make
      keys with `-` in them awkward to work with
    * Convert Dependency versions from the cargo format to something meson
      understands

    :param d: The mapping to fix
    :return: the fixed string
    """
    raw = {fixup_meson_varname(k): v for k, v in d.items()}
    if 'version' in raw:
        assert isinstance(raw['version'], str), 'for mypy'
        raw['version'] = version.convert(raw['version'])
    return T.cast('T.Union[manifest.FixedBuildTarget, manifest.FixedLibTarget, manifest.FixedDependency]', raw)


def _handle_unknown_keys(data: _UnknownKeysT, cls: T.Union[DataclassInstance, T.Type[DataclassInstance]],
                         msg: str) -> _UnknownKeysT:
    """Remove and warn on keys that are coming from cargo, but are unknown to
    our representations.

    This is intended to give users the possibility of things proceeding when a
    new key is added to Cargo.toml that we don't yet handle, but to still warn
    them that things might not work.

    :param data: The raw data to look at
    :param cls: The Dataclass derived type that will be created
    :param msg: the header for the error message. Usually something like "In N structure".
    :return: The original data structure, but with all unknown keys removed.
    """
    unexpected = set(data) - {x.name for x in dataclasses.fields(cls)}
    if unexpected:
        mlog.warning(msg, 'has unexpected keys', '"{}".'.format(', '.join(sorted(unexpected))),
                     _EXTRA_KEYS_WARNING)
        for k in unexpected:
            # Mypy and Pyright can't prove that this is okay
            del data[k]  # type: ignore[misc]
    return data


@dataclasses.dataclass
class Package:

    """Representation of a Cargo Package entry, with defaults filled in."""

    name: str
    version: str
    description: T.Optional[str] = None
    resolver: T.Optional[str] = None
    authors: T.List[str] = dataclasses.field(default_factory=list)
    edition: manifest.EDITION = '2015'
    rust_version: T.Optional[str] = None
    documentation: T.Optional[str] = None
    readme: T.Optional[str] = None
    homepage: T.Optional[str] = None
    repository: T.Optional[str] = None
    license: T.Optional[str] = None
    license_file: T.Optional[str] = None
    keywords: T.List[str] = dataclasses.field(default_factory=list)
    categories: T.List[str] = dataclasses.field(default_factory=list)
    workspace: T.Optional[str] = None
    build: T.Optional[str] = None
    links: T.Optional[str] = None
    exclude: T.List[str] = dataclasses.field(default_factory=list)
    include: T.List[str] = dataclasses.field(default_factory=list)
    publish: bool = True
    metadata: T.Dict[str, T.Any] = dataclasses.field(default_factory=dict)
    default_run: T.Optional[str] = None
    autolib: bool = True
    autobins: bool = True
    autoexamples: bool = True
    autotests: bool = True
    autobenches: bool = True
    api: str = dataclasses.field(init=False)

    def __post_init__(self) -> None:
        self.api = _version_to_api(self.version)

    @classmethod
    def from_raw(cls, raw: manifest.Package) -> Self:
        pkg = T.cast('manifest.FixedPackage',
                     {fixup_meson_varname(k): v for k, v in raw.items()})
        pkg = _handle_unknown_keys(pkg, cls, f'Package entry {pkg["name"]}')
        return cls(**pkg)

@dataclasses.dataclass
class SystemDependency:

    """ Representation of a Cargo system-deps entry
        https://docs.rs/system-deps/latest/system_deps
    """

    name: str
    version: T.List[str]
    optional: bool = False
    feature: T.Optional[str] = None
    feature_overrides: T.Dict[str, T.Dict[str, str]] = dataclasses.field(default_factory=dict)

    @classmethod
    def from_raw(cls, name: str, raw: T.Any) -> SystemDependency:
        if isinstance(raw, str):
            return cls(name, SystemDependency.convert_version(raw))
        name = raw.get('name', name)
        version = SystemDependency.convert_version(raw.get('version'))
        optional = raw.get('optional', False)
        feature = raw.get('feature')
        # Everything else are overrides when certain features are enabled.
        feature_overrides = {k: v for k, v in raw.items() if k not in {'name', 'version', 'optional', 'feature'}}
        return cls(name, version, optional, feature, feature_overrides)

    @staticmethod
    def convert_version(version: T.Optional[str]) -> T.List[str]:
        vers = version.split(',') if version is not None else []
        result: T.List[str] = []
        for v in vers:
            v = v.strip()
            if v[0] not in '><=':
                v = f'>={v}'
            result.append(v)
        return result

    def enabled(self, features: T.Set[str]) -> bool:
        return self.feature is None or self.feature in features

@dataclasses.dataclass
class Dependency:

    """Representation of a Cargo Dependency Entry."""

    name: dataclasses.InitVar[str]
    version: T.List[str]
    registry: T.Optional[str] = None
    git: T.Optional[str] = None
    branch: T.Optional[str] = None
    rev: T.Optional[str] = None
    path: T.Optional[str] = None
    optional: bool = False
    package: str = ''
    default_features: bool = True
    features: T.List[str] = dataclasses.field(default_factory=list)
    api: str = dataclasses.field(init=False)

    def __post_init__(self, name: str) -> None:
        self.package = self.package or name
        # Extract wanted API version from version constraints.
        api = set()
        for v in self.version:
            if v.startswith(('>=', '==')):
                api.add(_version_to_api(v[2:].strip()))
            elif v.startswith('='):
                api.add(_version_to_api(v[1:].strip()))
        if not api:
            self.api = '0'
        elif len(api) == 1:
            self.api = api.pop()
        else:
            raise MesonException(f'Cannot determine minimum API version from {self.version}.')

    @classmethod
    def from_raw(cls, name: str, raw: manifest.DependencyV) -> Dependency:
        """Create a dependency from a raw cargo dictionary"""
        if isinstance(raw, str):
            return cls(name, version.convert(raw))
        fixed = _handle_unknown_keys(_fixup_raw_mappings(raw), cls, f'Dependency entry {name}')
        return cls(name, **fixed)


@dataclasses.dataclass
class BuildTarget:

    name: str
    crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['lib'])
    path: dataclasses.InitVar[T.Optional[str]] = None

    # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-test-field
    # True for lib, bin, test
    test: bool = True

    # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-doctest-field
    # True for lib
    doctest: bool = False

    # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-bench-field
    # True for lib, bin, benchmark
    bench: bool = True

    # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-doc-field
    # True for libraries and binaries
    doc: bool = False

    harness: bool = True
    edition: manifest.EDITION = '2015'
    required_features: T.List[str] = dataclasses.field(default_factory=list)
    plugin: bool = False

    @classmethod
    def from_raw(cls, raw: manifest.BuildTarget) -> Self:
        name = raw.get('name', '<anonymous>')
        build = _handle_unknown_keys(_fixup_raw_mappings(raw), cls, f'Binary entry {name}')
        return cls(**build)

@dataclasses.dataclass
class Library(BuildTarget):

    """Representation of a Cargo Library Entry."""

    doctest: bool = True
    doc: bool = True
    path: str = os.path.join('src', 'lib.rs')
    proc_macro: bool = False
    crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['lib'])
    doc_scrape_examples: bool = True

    @classmethod
    def from_raw(cls, raw: manifest.LibTarget, fallback_name: str) -> Self:  # type: ignore[override]
        fixed = _fixup_raw_mappings(raw)

        # We need to set the name field if it's not set manually, including if
        # other fields are set in the lib section
        if 'name' not in fixed:
            fixed['name'] = fallback_name
        fixed = _handle_unknown_keys(fixed, cls, f'Library entry {fixed["name"]}')

        return cls(**fixed)


@dataclasses.dataclass
class Binary(BuildTarget):

    """Representation of a Cargo Bin Entry."""

    doc: bool = True


@dataclasses.dataclass
class Test(BuildTarget):

    """Representation of a Cargo Test Entry."""

    bench: bool = True


@dataclasses.dataclass
class Benchmark(BuildTarget):

    """Representation of a Cargo Benchmark Entry."""

    test: bool = True


@dataclasses.dataclass
class Example(BuildTarget):

    """Representation of a Cargo Example Entry."""

    crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['bin'])


@dataclasses.dataclass
class Manifest:

    """Cargo Manifest definition.

    Most of these values map up to the Cargo Manifest, but with default values
    if not provided.

    Cargo subprojects can contain what Meson wants to treat as multiple,
    interdependent, subprojects.

    :param path: the path within the cargo subproject.
    """

    package: Package
    dependencies: T.Dict[str, Dependency]
    dev_dependencies: T.Dict[str, Dependency]
    build_dependencies: T.Dict[str, Dependency]
    system_dependencies: T.Dict[str, SystemDependency] = dataclasses.field(init=False)
    lib: Library
    bin: T.List[Binary]
    test: T.List[Test]
    bench: T.List[Benchmark]
    example: T.List[Example]
    features: T.Dict[str, T.List[str]]
    target: T.Dict[str, T.Dict[str, Dependency]]
    path: str = ''

    def __post_init__(self) -> None:
        self.features.setdefault('default', [])
        self.system_dependencies = {k: SystemDependency.from_raw(k, v) for k, v in self.package.metadata.get('system-deps', {}).items()}


def _convert_manifest(raw_manifest: manifest.Manifest, subdir: str, path: str = '') -> Manifest:
    return Manifest(
        Package.from_raw(raw_manifest['package']),
        {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('dependencies', {}).items()},
        {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('dev-dependencies', {}).items()},
        {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('build-dependencies', {}).items()},
        Library.from_raw(raw_manifest.get('lib', {}), raw_manifest['package']['name']),
        [Binary.from_raw(b) for b in raw_manifest.get('bin', {})],
        [Test.from_raw(b) for b in raw_manifest.get('test', {})],
        [Benchmark.from_raw(b) for b in raw_manifest.get('bench', {})],
        [Example.from_raw(b) for b in raw_manifest.get('example', {})],
        raw_manifest.get('features', {}),
        {k: {k2: Dependency.from_raw(k2, v2) for k2, v2 in v.get('dependencies', {}).items()}
         for k, v in raw_manifest.get('target', {}).items()},
        path,
    )


def _version_to_api(version: str) -> str:
    # x.y.z -> x
    # 0.x.y -> 0.x
    # 0.0.x -> 0
    vers = version.split('.')
    if int(vers[0]) != 0:
        return vers[0]
    elif len(vers) >= 2 and int(vers[1]) != 0:
        return f'0.{vers[1]}'
    return '0'


def _dependency_name(package_name: str, api: str) -> str:
    basename = package_name[:-3] if package_name.endswith('-rs') else package_name
    return f'{basename}-{api}-rs'


def _dependency_varname(package_name: str) -> str:
    return f'{fixup_meson_varname(package_name)}_dep'


def _extra_args_varname() -> str:
    return 'extra_args'


def _extra_deps_varname() -> str:
    return 'extra_deps'


class PackageState:
    def __init__(self, manifest: Manifest, downloaded: bool) -> None:
        self.manifest = manifest
        self.downloaded = downloaded
        self.features: T.Set[str] = set()
        self.required_deps: T.Set[str] = set()
        self.optional_deps_features: T.Dict[str, T.Set[str]] = collections.defaultdict(set)


@dataclasses.dataclass(frozen=True)
class PackageKey:
    package_name: str
    api: str


class Interpreter:
    def __init__(self, env: Environment) -> None:
        self.environment = env
        self.host_rustc = T.cast('RustCompiler', self.environment.coredata.compilers[MachineChoice.HOST]['rust'])
        # Map Cargo.toml's subdir to loaded manifest.
        self.manifests: T.Dict[str, Manifest] = {}
        # Map of cargo package (name + api) to its state
        self.packages: T.Dict[PackageKey, PackageState] = {}
        # Rustc's config
        self.cfgs = self._get_cfgs()

    def interpret(self, subdir: str) -> mparser.CodeBlockNode:
        manifest = self._load_manifest(subdir)
        pkg, cached = self._fetch_package(manifest.package.name, manifest.package.api)
        if not cached:
            # This is an entry point, always enable the 'default' feature.
            # FIXME: We should have a Meson option similar to `cargo build --no-default-features`
            self._enable_feature(pkg, 'default')

        # Build an AST for this package
        filename = os.path.join(self.environment.source_dir, subdir, 'Cargo.toml')
        build = builder.Builder(filename)
        ast = self._create_project(pkg, build)
        ast += [
            build.assign(build.function('import', [build.string('rust')]), 'rust'),
            build.function('message', [
                build.string('Enabled features:'),
                build.array([build.string(f) for f in pkg.features]),
            ]),
        ]
        ast += self._create_dependencies(pkg, build)
        ast += self._create_meson_subdir(build)

        # Libs are always auto-discovered and there's no other way to handle them,
        # which is unfortunate for reproducability
        if os.path.exists(os.path.join(self.environment.source_dir, subdir, pkg.manifest.path, pkg.manifest.lib.path)):
            for crate_type in pkg.manifest.lib.crate_type:
                ast.extend(self._create_lib(pkg, build, crate_type))

        return build.block(ast)

    def _fetch_package(self, package_name: str, api: str) -> T.Tuple[PackageState, bool]:
        key = PackageKey(package_name, api)
        pkg = self.packages.get(key)
        if pkg:
            return pkg, True
        meson_depname = _dependency_name(package_name, api)
        subdir, _ = self.environment.wrap_resolver.resolve(meson_depname)
        subprojects_dir = os.path.join(subdir, 'subprojects')
        self.environment.wrap_resolver.load_and_merge(subprojects_dir, T.cast('SubProject', meson_depname))
        manifest = self._load_manifest(subdir)
        downloaded = \
            meson_depname in self.environment.wrap_resolver.wraps and \
            self.environment.wrap_resolver.wraps[meson_depname].type is not None
        pkg = PackageState(manifest, downloaded)
        self.packages[key] = pkg
        # Merge target specific dependencies that are enabled
        for condition, dependencies in manifest.target.items():
            if cfg.eval_cfg(condition, self.cfgs):
                manifest.dependencies.update(dependencies)
        # Fetch required dependencies recursively.
        for depname, dep in manifest.dependencies.items():
            if not dep.optional:
                self._add_dependency(pkg, depname)
        return pkg, False

    def _dep_package(self, dep: Dependency) -> PackageState:
        return self.packages[PackageKey(dep.package, dep.api)]

    def _load_manifest(self, subdir: str) -> Manifest:
        manifest_ = self.manifests.get(subdir)
        if not manifest_:
            filename = os.path.join(self.environment.source_dir, subdir, 'Cargo.toml')
            raw = load_toml(filename)
            if 'package' in raw:
                raw_manifest = T.cast('manifest.Manifest', raw)
                manifest_ = _convert_manifest(raw_manifest, subdir)
                self.manifests[subdir] = manifest_
            else:
                raise MesonException(f'{subdir}/Cargo.toml does not have [package] section')
        return manifest_

    def _add_dependency(self, pkg: PackageState, depname: str) -> None:
        if depname in pkg.required_deps:
            return
        dep = pkg.manifest.dependencies.get(depname)
        if not dep:
            if depname in itertools.chain(pkg.manifest.dev_dependencies, pkg.manifest.build_dependencies):
                # FIXME: Not supported yet
                return
            raise MesonException(f'Dependency {depname} not defined in {pkg.manifest.package.name} manifest')
        pkg.required_deps.add(depname)
        dep_pkg, _ = self._fetch_package(dep.package, dep.api)
        if dep.default_features:
            self._enable_feature(dep_pkg, 'default')
        for f in dep.features:
            self._enable_feature(dep_pkg, f)
        for f in pkg.optional_deps_features[depname]:
            self._enable_feature(dep_pkg, f)

    def _enable_feature(self, pkg: PackageState, feature: str) -> None:
        if feature in pkg.features:
            return
        pkg.features.add(feature)
        # A feature can also be a dependency.
        if feature in pkg.manifest.dependencies:
            self._add_dependency(pkg, feature)
        # Recurse on extra features and dependencies this feature pulls.
        # https://doc.rust-lang.org/cargo/reference/features.html#the-features-section
        for f in pkg.manifest.features.get(feature, []):
            if '/' in f:
                depname, dep_f = f.split('/', 1)
                if depname[-1] == '?':
                    depname = depname[:-1]
                    if depname in pkg.required_deps:
                        dep = pkg.manifest.dependencies[depname]
                        dep_pkg = self._dep_package(dep)
                        self._enable_feature(dep_pkg, dep_f)
                    else:
                        # This feature will be enabled only if that dependency
                        # is later added.
                        pkg.optional_deps_features[depname].add(dep_f)
                else:
                    self._add_dependency(pkg, depname)
                    dep = pkg.manifest.dependencies.get(depname)
                    if dep:
                        dep_pkg = self._dep_package(dep)
                        self._enable_feature(dep_pkg, dep_f)
            elif f.startswith('dep:'):
                self._add_dependency(pkg, f[4:])
            else:
                self._enable_feature(pkg, f)

    def _get_cfgs(self) -> T.Dict[str, str]:
        cfgs = self.host_rustc.get_cfgs().copy()
        rustflags = self.environment.coredata.get_external_args(MachineChoice.HOST, 'rust')
        rustflags_i = iter(rustflags)
        for i in rustflags_i:
            if i == '--cfg':
                cfgs.append(next(rustflags_i))
        return dict(self._split_cfg(i) for i in cfgs)

    @staticmethod
    def _split_cfg(cfg: str) -> T.Tuple[str, str]:
        pair = cfg.split('=', maxsplit=1)
        value = pair[1] if len(pair) > 1 else ''
        if value and value[0] == '"':
            value = value[1:-1]
        return pair[0], value

    def _create_project(self, pkg: PackageState, build: builder.Builder) -> T.List[mparser.BaseNode]:
        """Create the project() function call

        :param pkg: The package to generate from
        :param build: The AST builder
        :return: a list nodes
        """
        default_options: T.List[mparser.BaseNode] = []
        default_options.append(build.string(f'rust_std={pkg.manifest.package.edition}'))
        default_options.append(build.string(f'build.rust_std={pkg.manifest.package.edition}'))
        if pkg.downloaded:
            default_options.append(build.string('warning_level=0'))

        args: T.List[mparser.BaseNode] = []
        args.extend([
            build.string(pkg.manifest.package.name),
            build.string('rust'),
        ])
        kwargs: T.Dict[str, mparser.BaseNode] = {
            'version': build.string(pkg.manifest.package.version),
            # Always assume that the generated meson is using the latest features
            # This will warn when when we generate deprecated code, which is helpful
            # for the upkeep of the module
            'meson_version': build.string(f'>= {coredata.stable_version}'),
            'default_options': build.array(default_options),
        }
        if pkg.manifest.package.license:
            kwargs['license'] = build.string(pkg.manifest.package.license)
        elif pkg.manifest.package.license_file:
            kwargs['license_files'] = build.string(pkg.manifest.package.license_file)

        return [build.function('project', args, kwargs)]

    def _create_dependencies(self, pkg: PackageState, build: builder.Builder) -> T.List[mparser.BaseNode]:
        ast: T.List[mparser.BaseNode] = []
        for depname in pkg.required_deps:
            dep = pkg.manifest.dependencies[depname]
            ast += self._create_dependency(dep, build)
        ast.append(build.assign(build.array([]), 'system_deps_args'))
        for name, sys_dep in pkg.manifest.system_dependencies.items():
            if sys_dep.enabled(pkg.features):
                ast += self._create_system_dependency(name, sys_dep, build)
        return ast

    def _create_system_dependency(self, name: str, dep: SystemDependency, build: builder.Builder) -> T.List[mparser.BaseNode]:
        kw = {
            'version': build.array([build.string(s) for s in dep.version]),
            'required': build.bool(not dep.optional),
        }
        varname = f'{fixup_meson_varname(name)}_system_dep'
        cfg = f'system_deps_have_{fixup_meson_varname(name)}'
        return [
            build.assign(
                build.function(
                    'dependency',
                    [build.string(dep.name)],
                    kw,
                ),
                varname,
            ),
            build.if_(
                build.method('found', build.identifier(varname)), build.block([
                    build.plusassign(
                        build.array([build.string('--cfg'), build.string(cfg)]),
                        'system_deps_args'
                    ),
                ])
            ),
        ]

    def _create_dependency(self, dep: Dependency, build: builder.Builder) -> T.List[mparser.BaseNode]:
        pkg = self._dep_package(dep)
        kw = {
            'version': build.array([build.string(s) for s in dep.version]),
        }
        # Lookup for this dependency with the features we want in default_options kwarg.
        #
        # However, this subproject could have been previously configured with a
        # different set of features. Cargo collects the set of features globally
        # but Meson can only use features enabled by the first call that triggered
        # the configuration of that subproject.
        #
        # Verify all features that we need are actually enabled for that dependency,
        # otherwise abort with an error message. The user has to set the corresponding
        # option manually with -Dxxx-rs:feature-yyy=true, or the main project can do
        # that in its project(..., default_options: ['xxx-rs:feature-yyy=true']).
        return [
            # xxx_dep = dependency('xxx', version : ...)
            build.assign(
                build.function(
                    'dependency',
                    [build.string(_dependency_name(dep.package, dep.api))],
                    kw,
                ),
                _dependency_varname(dep.package),
            ),
            # actual_features = xxx_dep.get_variable('features', default_value : '').split(',')
            build.assign(
                build.method(
                    'split',
                    build.method(
                        'get_variable',
                        build.identifier(_dependency_varname(dep.package)),
                        [build.string('features')],
                        {'default_value': build.string('')}
                    ),
                    [build.string(',')],
                ),
                'actual_features'
            ),
            # needed_features = [f1, f2, ...]
            # foreach f : needed_features
            #   if f not in actual_features
            #     error()
            #   endif
            # endforeach
            build.assign(build.array([build.string(f) for f in pkg.features]), 'needed_features'),
            build.foreach(['f'], build.identifier('needed_features'), build.block([
                build.if_(build.not_in(build.identifier('f'), build.identifier('actual_features')), build.block([
                    build.function('error', [
                        build.string('Dependency'),
                        build.string(_dependency_name(dep.package, dep.api)),
                        build.string('previously configured with features'),
                        build.identifier('actual_features'),
                        build.string('but need'),
                        build.identifier('needed_features'),
                    ])
                ]))
            ])),
        ]

    def _create_meson_subdir(self, build: builder.Builder) -> T.List[mparser.BaseNode]:
        # Allow Cargo subprojects to add extra Rust args in meson/meson.build file.
        # This is used to replace build.rs logic.

        # extra_args = []
        # extra_deps = []
        # fs = import('fs')
        # if fs.is_dir('meson')
        #  subdir('meson')
        # endif
        return [
            build.assign(build.array([]), _extra_args_varname()),
            build.assign(build.array([]), _extra_deps_varname()),
            build.assign(build.function('import', [build.string('fs')]), 'fs'),
            build.if_(build.method('is_dir', build.identifier('fs'), [build.string('meson')]),
                      build.block([build.function('subdir', [build.string('meson')])]))
        ]

    def _create_lib(self, pkg: PackageState, build: builder.Builder, crate_type: manifest.CRATE_TYPE) -> T.List[mparser.BaseNode]:
        dependencies: T.List[mparser.BaseNode] = []
        dependency_map: T.Dict[mparser.BaseNode, mparser.BaseNode] = {}
        for name in pkg.required_deps:
            dep = pkg.manifest.dependencies[name]
            dependencies.append(build.identifier(_dependency_varname(dep.package)))
            if name != dep.package:
                dep_pkg = self._dep_package(dep)
                dep_lib_name = dep_pkg.manifest.lib.name
                dependency_map[build.string(fixup_meson_varname(dep_lib_name))] = build.string(name)
        for name, sys_dep in pkg.manifest.system_dependencies.items():
            if sys_dep.enabled(pkg.features):
                dependencies.append(build.identifier(f'{fixup_meson_varname(name)}_system_dep'))

        rust_args: T.List[mparser.BaseNode] = [
            build.identifier('features_args'),
            build.identifier(_extra_args_varname()),
            build.identifier('system_deps_args'),
        ]

        dependencies.append(build.identifier(_extra_deps_varname()))

        posargs: T.List[mparser.BaseNode] = [
            build.string(fixup_meson_varname(pkg.manifest.lib.name)),
            build.string(pkg.manifest.lib.path),
        ]

        kwargs: T.Dict[str, mparser.BaseNode] = {
            'dependencies': build.array(dependencies),
            'rust_dependency_map': build.dict(dependency_map),
            'rust_args': build.array(rust_args),
        }

        lib: mparser.BaseNode
        if pkg.manifest.lib.proc_macro or crate_type == 'proc-macro':
            lib = build.method('proc_macro', build.identifier('rust'), posargs, kwargs)
        else:
            if crate_type in {'lib', 'rlib', 'staticlib'}:
                target_type = 'static_library'
            elif crate_type in {'dylib', 'cdylib'}:
                target_type = 'shared_library'
            else:
                raise MesonException(f'Unsupported crate type {crate_type}')
            if crate_type in {'staticlib', 'cdylib'}:
                kwargs['rust_abi'] = build.string('c')
            lib = build.function(target_type, posargs, kwargs)

        features_args: T.List[mparser.BaseNode] = []
        for f in pkg.features:
            features_args += [build.string('--cfg'), build.string(f'feature="{f}"')]

        # features_args = ['--cfg', 'feature="f1"', ...]
        # lib = xxx_library()
        # dep = declare_dependency()
        # meson.override_dependency()
        return [
            build.assign(build.array(features_args), 'features_args'),
            build.assign(lib, 'lib'),
            build.assign(
                build.function(
                    'declare_dependency',
                    kw={
                        'link_with': build.identifier('lib'),
                        'variables': build.dict({
                            build.string('features'): build.string(','.join(pkg.features)),
                        })
                    },
                ),
                'dep'
            ),
            build.method(
                'override_dependency',
                build.identifier('meson'),
                [
                    build.string(_dependency_name(pkg.manifest.package.name, pkg.manifest.package.api)),
                    build.identifier('dep'),
                ],
            ),
        ]


def load_wraps(source_dir: str, subproject_dir: str) -> T.List[PackageDefinition]:
    """ Convert Cargo.lock into a list of wraps """

    wraps: T.List[PackageDefinition] = []
    filename = os.path.join(source_dir, 'Cargo.lock')
    if os.path.exists(filename):
        try:
            cargolock = T.cast('manifest.CargoLock', load_toml(filename))
        except TomlImplementationMissing as e:
            mlog.warning('Failed to load Cargo.lock:', str(e), fatal=False)
            return wraps
        for package in cargolock['package']:
            name = package['name']
            version = package['version']
            subp_name = _dependency_name(name, _version_to_api(version))
            source = package.get('source')
            if source is None:
                # This is project's package, or one of its workspace members.
                pass
            elif source == 'registry+https://github.com/rust-lang/crates.io-index':
                checksum = package.get('checksum')
                if checksum is None:
                    checksum = cargolock['metadata'][f'checksum {name} {version} ({source})']
                url = f'https://crates.io/api/v1/crates/{name}/{version}/download'
                directory = f'{name}-{version}'
                wraps.append(PackageDefinition.from_values(subp_name, subproject_dir, 'file', {
                    'directory': directory,
                    'source_url': url,
                    'source_filename': f'{directory}.tar.gz',
                    'source_hash': checksum,
                    'method': 'cargo',
                }))
            elif source.startswith('git+'):
                parts = urllib.parse.urlparse(source[4:])
                query = urllib.parse.parse_qs(parts.query)
                branch = query['branch'][0] if 'branch' in query else ''
                revision = parts.fragment or branch
                url = urllib.parse.urlunparse(parts._replace(params='', query='', fragment=''))
                wraps.append(PackageDefinition.from_values(subp_name, subproject_dir, 'git', {
                    'directory': name,
                    'url': url,
                    'revision': revision,
                    'method': 'cargo',
                }))
            else:
                mlog.warning(f'Unsupported source URL in {filename}: {source}')
    return wraps
