# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

from itertools import chain
import warnings

import portage
from portage.cache.mappings import slot_dict_class
from portage.const import EBUILD_PHASES
from portage.dep import (
    Atom,
    check_required_use,
    use_reduce,
    paren_enclose,
    _slot_separator,
    _repo_separator,
)
from portage.dep.soname.parse import parse_soname_deps
from portage.versions import _pkg_str, _unknown_repo
from portage.eapi import _get_eapi_attrs, eapi_has_use_aliases
from portage.exception import InvalidData, InvalidDependString
from portage.localization import _
from _emerge.Task import Task


class Package(Task):

    __hash__ = Task.__hash__
    __slots__ = (
        "built",
        "cpv",
        "depth",
        "installed",
        "onlydeps",
        "operation",
        "root_config",
        "type_name",
        "category",
        "counter",
        "cp",
        "cpv_split",
        "inherited",
        "iuse",
        "mtime",
        "pf",
        "root",
        "slot",
        "sub_slot",
        "slot_atom",
        "version",
    ) + (
        "_invalid",
        "_masks",
        "_metadata",
        "_provided_cps",
        "_raw_metadata",
        "_provides",
        "_requires",
        "_use",
        "_validated_atoms",
        "_visible",
    )

    metadata_keys = [
        "BDEPEND",
        "BUILD_ID",
        "BUILD_TIME",
        "CHOST",
        "COUNTER",
        "DEFINED_PHASES",
        "DEPEND",
        "EAPI",
        "IDEPEND",
        "INHERITED",
        "IUSE",
        "KEYWORDS",
        "LICENSE",
        "MD5",
        "PDEPEND",
        "PROVIDES",
        "RDEPEND",
        "repository",
        "REQUIRED_USE",
        "PROPERTIES",
        "REQUIRES",
        "RESTRICT",
        "SIZE",
        "SLOT",
        "USE",
        "_mtime_",
    ]

    _dep_keys = ("BDEPEND", "DEPEND", "IDEPEND", "PDEPEND", "RDEPEND")
    _buildtime_keys = ("BDEPEND", "DEPEND")
    _runtime_keys = ("IDEPEND", "PDEPEND", "RDEPEND")
    _use_conditional_misc_keys = ("LICENSE", "PROPERTIES", "RESTRICT")
    UNKNOWN_REPO = _unknown_repo

    def __init__(self, **kwargs):
        metadata = _PackageMetadataWrapperBase(kwargs.pop("metadata"))
        Task.__init__(self, **kwargs)
        # the SlotObject constructor assigns self.root_config from keyword args
        # and is an instance of a '_emerge.RootConfig.RootConfig class
        self.root = self.root_config.root
        self._raw_metadata = metadata
        self._metadata = _PackageMetadataWrapper(self, metadata)
        if not self.built:
            self._metadata["CHOST"] = self.root_config.settings.get("CHOST", "")
        eapi_attrs = _get_eapi_attrs(self.eapi)

        try:
            db = self.cpv._db
        except AttributeError:
            if self.built:
                # For independence from the source ebuild repository and
                # profile implicit IUSE state, require the _db attribute
                # for built packages.
                raise
            db = self.root_config.trees["porttree"].dbapi

        self.cpv = _pkg_str(
            self.cpv, metadata=self._metadata, settings=self.root_config.settings, db=db
        )
        if hasattr(self.cpv, "slot_invalid"):
            self._invalid_metadata(
                "SLOT.invalid", "SLOT: invalid value: '%s'" % self._metadata["SLOT"]
            )
        self.cpv_split = self.cpv.cpv_split
        self.category, self.pf = portage.catsplit(self.cpv)
        self.cp = self.cpv.cp
        self.version = self.cpv.version
        self.slot = self.cpv.slot
        self.sub_slot = self.cpv.sub_slot
        self.slot_atom = Atom("%s%s%s" % (self.cp, _slot_separator, self.slot))
        # sync metadata with validated repo (may be UNKNOWN_REPO)
        self._metadata["repository"] = self.cpv.repo

        if self.root_config.settings.local_config:
            implicit_match = db._iuse_implicit_cnstr(self.cpv, self._metadata)
        else:
            implicit_match = db._repoman_iuse_implicit_cnstr(self.cpv, self._metadata)
        usealiases = self.root_config.settings._use_manager.getUseAliases(self)
        self.iuse = self._iuse(
            self, self._metadata["IUSE"].split(), implicit_match, usealiases, self.eapi
        )

        if (self.iuse.enabled or self.iuse.disabled) and not eapi_attrs.iuse_defaults:
            if not self.installed:
                self._invalid_metadata(
                    "EAPI.incompatible",
                    "IUSE contains defaults, but EAPI doesn't allow them",
                )
        if self.inherited is None:
            self.inherited = frozenset()

        if self.operation is None:
            if self.onlydeps or self.installed:
                self.operation = "nomerge"
            else:
                self.operation = "merge"

        self._hash_key = Package._gen_hash_key(
            cpv=self.cpv,
            installed=self.installed,
            onlydeps=self.onlydeps,
            operation=self.operation,
            repo_name=self.cpv.repo,
            root_config=self.root_config,
            type_name=self.type_name,
        )
        self._hash_value = hash(self._hash_key)

    @property
    def eapi(self):
        return self._metadata["EAPI"]

    @property
    def build_id(self):
        return self.cpv.build_id

    @property
    def build_time(self):
        if not self.built:
            raise AttributeError("build_time")
        return self.cpv.build_time

    @property
    def defined_phases(self):
        return self._metadata.defined_phases

    @property
    def properties(self):
        return self._metadata.properties

    @property
    def provided_cps(self):
        return (self.cp,)

    @property
    def restrict(self):
        return self._metadata.restrict

    @property
    def metadata(self):
        warnings.warn(
            "_emerge.Package.Package.metadata is deprecated",
            DeprecationWarning,
            stacklevel=3,
        )
        return self._metadata

    # These are calculated on-demand, so that they are calculated
    # after FakeVartree applies its metadata tweaks.
    @property
    def invalid(self):
        if self._invalid is None:
            self._validate_deps()
            if self._invalid is None:
                self._invalid = False
        return self._invalid

    @property
    def masks(self):
        if self._masks is None:
            self._masks = self._eval_masks()
        return self._masks

    @property
    def visible(self):
        if self._visible is None:
            self._visible = self._eval_visiblity(self.masks)
        return self._visible

    @property
    def validated_atoms(self):
        """
        Returns *all* validated atoms from the deps, regardless
        of USE conditionals, with USE conditionals inside
        atoms left unevaluated.
        """
        if self._validated_atoms is None:
            self._validate_deps()
        return self._validated_atoms

    @property
    def stable(self):
        return self.cpv.stable

    @property
    def provides(self):
        self.invalid
        return self._provides

    @property
    def requires(self):
        self.invalid
        return self._requires

    @classmethod
    def _gen_hash_key(
        cls,
        cpv=None,
        installed=None,
        onlydeps=None,
        operation=None,
        repo_name=None,
        root_config=None,
        type_name=None,
        **kwargs
    ):

        if operation is None:
            if installed or onlydeps:
                operation = "nomerge"
            else:
                operation = "merge"

        root = None
        if root_config is not None:
            root = root_config.root
        else:
            raise TypeError("root_config argument is required")

        elements = [type_name, root, str(cpv), operation]

        # For installed (and binary) packages we don't care for the repo
        # when it comes to hashing, because there can only be one cpv.
        # So overwrite the repo_key with type_name.
        if type_name is None:
            raise TypeError("type_name argument is required")
        elif type_name == "ebuild":
            if repo_name is None:
                raise AssertionError(
                    "Package._gen_hash_key() " + "called without 'repo_name' argument"
                )
            elements.append(repo_name)
        elif type_name == "binary":
            # Including a variety of fingerprints in the hash makes
            # it possible to simultaneously consider multiple similar
            # packages. Note that digests are not included here, since
            # they are relatively expensive to compute, and they may
            # not necessarily be available.
            elements.extend([cpv.build_id, cpv.file_size, cpv.build_time, cpv.mtime])
        else:
            # For installed (and binary) packages we don't care for the repo
            # when it comes to hashing, because there can only be one cpv.
            # So overwrite the repo_key with type_name.
            elements.append(type_name)

        return tuple(elements)

    def _validate_deps(self):
        """
        Validate deps. This does not trigger USE calculation since that
        is expensive for ebuilds and therefore we want to avoid doing
        it unnecessarily (like for masked packages).
        """
        eapi = self.eapi
        dep_eapi = eapi
        dep_valid_flag = self.iuse.is_valid_flag
        if self.installed:
            # Ignore EAPI.incompatible and conditionals missing
            # from IUSE for installed packages since these issues
            # aren't relevant now (re-evaluate when new EAPIs are
            # deployed).
            dep_eapi = None
            dep_valid_flag = None

        validated_atoms = []
        for k in self._dep_keys:
            v = self._metadata.get(k)
            if not v:
                continue
            try:
                atoms = use_reduce(
                    v,
                    eapi=dep_eapi,
                    matchall=True,
                    is_valid_flag=dep_valid_flag,
                    token_class=Atom,
                    flat=True,
                )
            except InvalidDependString as e:
                self._metadata_exception(k, e)
            else:
                validated_atoms.extend(atoms)
                if not self.built:
                    for atom in atoms:
                        if not isinstance(atom, Atom):
                            continue
                        if atom.slot_operator_built:
                            e = InvalidDependString(
                                _(
                                    "Improper context for slot-operator "
                                    '"built" atom syntax: %s'
                                )
                                % (atom.unevaluated_atom,)
                            )
                            self._metadata_exception(k, e)

        self._validated_atoms = tuple(
            set(atom for atom in validated_atoms if isinstance(atom, Atom))
        )

        for k in self._use_conditional_misc_keys:
            v = self._metadata.get(k)
            if not v:
                continue
            try:
                use_reduce(
                    v, eapi=dep_eapi, matchall=True, is_valid_flag=dep_valid_flag
                )
            except InvalidDependString as e:
                self._metadata_exception(k, e)

        k = "REQUIRED_USE"
        v = self._metadata.get(k)
        if v and not self.built:
            if not _get_eapi_attrs(eapi).required_use:
                self._invalid_metadata(
                    "EAPI.incompatible",
                    "REQUIRED_USE set, but EAPI='%s' doesn't allow it" % eapi,
                )
            else:
                try:
                    check_required_use(v, (), self.iuse.is_valid_flag, eapi=eapi)
                except InvalidDependString as e:
                    self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

        k = "SRC_URI"
        v = self._metadata.get(k)
        if v:
            try:
                use_reduce(
                    v,
                    is_src_uri=True,
                    eapi=eapi,
                    matchall=True,
                    is_valid_flag=self.iuse.is_valid_flag,
                )
            except InvalidDependString as e:
                if not self.installed:
                    self._metadata_exception(k, e)

        if self.built:
            k = "PROVIDES"
            try:
                self._provides = frozenset(parse_soname_deps(self._metadata[k]))
            except InvalidData as e:
                self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

            k = "REQUIRES"
            try:
                self._requires = frozenset(parse_soname_deps(self._metadata[k]))
            except InvalidData as e:
                self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

    def copy(self):
        return Package(
            built=self.built,
            cpv=self.cpv,
            depth=self.depth,
            installed=self.installed,
            metadata=self._raw_metadata,
            onlydeps=self.onlydeps,
            operation=self.operation,
            root_config=self.root_config,
            type_name=self.type_name,
        )

    def _eval_masks(self):
        masks = {}
        settings = self.root_config.settings

        if self.invalid is not False:
            masks["invalid"] = self.invalid

        if not settings._accept_chost(self.cpv, self._metadata):
            masks["CHOST"] = self._metadata["CHOST"]

        eapi = self.eapi
        if not portage.eapi_is_supported(eapi):
            masks["EAPI.unsupported"] = eapi
        if portage._eapi_is_deprecated(eapi):
            masks["EAPI.deprecated"] = eapi

        missing_keywords = settings._getMissingKeywords(self.cpv, self._metadata)
        if missing_keywords:
            masks["KEYWORDS"] = missing_keywords

        try:
            missing_properties = settings._getMissingProperties(
                self.cpv, self._metadata
            )
            if missing_properties:
                masks["PROPERTIES"] = missing_properties
        except InvalidDependString:
            # already recorded as 'invalid'
            pass

        try:
            missing_restricts = settings._getMissingRestrict(self.cpv, self._metadata)
            if missing_restricts:
                masks["RESTRICT"] = missing_restricts
        except InvalidDependString:
            # already recorded as 'invalid'
            pass

        mask_atom = settings._getMaskAtom(self.cpv, self._metadata)
        if mask_atom is not None:
            masks["package.mask"] = mask_atom

        try:
            missing_licenses = settings._getMissingLicenses(self.cpv, self._metadata)
            if missing_licenses:
                masks["LICENSE"] = missing_licenses
        except InvalidDependString:
            # already recorded as 'invalid'
            pass

        if not masks:
            masks = False

        return masks

    def _eval_visiblity(self, masks):

        if masks is not False:

            if "EAPI.unsupported" in masks:
                return False

            if "invalid" in masks:
                return False

            if not self.installed and (
                "CHOST" in masks
                or "EAPI.deprecated" in masks
                or "KEYWORDS" in masks
                or "PROPERTIES" in masks
                or "RESTRICT" in masks
            ):
                return False

            if "package.mask" in masks or "LICENSE" in masks:
                return False

        return True

    def get_keyword_mask(self):
        """returns None, 'missing', or 'unstable'."""

        missing = self.root_config.settings._getRawMissingKeywords(
            self.cpv, self._metadata
        )

        if not missing:
            return None

        if "**" in missing:
            return "missing"

        global_accept_keywords = frozenset(
            self.root_config.settings.get("ACCEPT_KEYWORDS", "").split()
        )

        for keyword in missing:
            if keyword.lstrip("~") in global_accept_keywords:
                return "unstable"

        return "missing"

    def isHardMasked(self):
        """returns a bool if the cpv is in the list of
        expanded pmaskdict[cp] available ebuilds"""
        pmask = self.root_config.settings._getRawMaskAtom(self.cpv, self._metadata)
        return pmask is not None

    def _metadata_exception(self, k, e):

        if k.endswith("DEPEND"):
            qacat = "dependency.syntax"
        else:
            qacat = k + ".syntax"

        if not self.installed:
            categorized_error = False
            if e.errors:
                for error in e.errors:
                    if getattr(error, "category", None) is None:
                        continue
                    categorized_error = True
                    self._invalid_metadata(error.category, "%s: %s" % (k, error))

            if not categorized_error:
                self._invalid_metadata(qacat, "%s: %s" % (k, e))
        else:
            # For installed packages, show the path of the file
            # containing the invalid metadata, since the user may
            # want to fix the deps by hand.
            vardb = self.root_config.trees["vartree"].dbapi
            path = vardb.getpath(self.cpv, filename=k)
            self._invalid_metadata(qacat, "%s: %s in '%s'" % (k, e, path))

    def _invalid_metadata(self, msg_type, msg):
        if self._invalid is None:
            self._invalid = {}
        msgs = self._invalid.get(msg_type)
        if msgs is None:
            msgs = []
            self._invalid[msg_type] = msgs
        msgs.append(msg)

    def __str__(self):
        if self.operation == "merge":
            if self.type_name == "binary":
                cpv_color = "PKG_BINARY_MERGE"
            else:
                cpv_color = "PKG_MERGE"
        elif self.operation == "uninstall":
            cpv_color = "PKG_UNINSTALL"
        else:
            cpv_color = "PKG_NOMERGE"

        build_id_str = ""
        if isinstance(self.cpv.build_id, int) and self.cpv.build_id > 0:
            build_id_str = "-%s" % self.cpv.build_id

        s = "(%s, %s" % (
            portage.output.colorize(
                cpv_color,
                self.cpv
                + build_id_str
                + _slot_separator
                + self.slot
                + "/"
                + self.sub_slot
                + _repo_separator
                + self.repo,
            ),
            self.type_name,
        )

        if self.type_name == "installed":
            if self.root_config.settings["ROOT"] != "/":
                s += " in '%s'" % self.root_config.settings["ROOT"]
            if self.operation == "uninstall":
                s += " scheduled for uninstall"
        else:
            if self.operation == "merge":
                s += " scheduled for merge"
                if self.root_config.settings["ROOT"] != "/":
                    s += " to '%s'" % self.root_config.settings["ROOT"]
        s += ")"
        return s

    class _use_class:

        __slots__ = ("enabled", "_expand", "_expand_hidden", "_force", "_pkg", "_mask")

        # Share identical frozenset instances when available.
        _frozensets = {}

        def __init__(self, pkg, enabled_flags):
            self._pkg = pkg
            self._expand = None
            self._expand_hidden = None
            self._force = None
            self._mask = None
            if eapi_has_use_aliases(pkg.eapi):
                for enabled_flag in enabled_flags:
                    enabled_flags.extend(pkg.iuse.alias_mapping.get(enabled_flag, []))
            self.enabled = frozenset(enabled_flags)
            if pkg.built:
                # Use IUSE to validate USE settings for built packages,
                # in case the package manager that built this package
                # failed to do that for some reason (or in case of
                # data corruption).
                missing_iuse = pkg.iuse.get_missing_iuse(self.enabled)
                if missing_iuse:
                    self.enabled = self.enabled.difference(missing_iuse)

        def _init_force_mask(self):
            pkgsettings = self._pkg._get_pkgsettings()
            frozensets = self._frozensets
            s = frozenset(pkgsettings.get("USE_EXPAND", "").lower().split())
            self._expand = frozensets.setdefault(s, s)
            s = frozenset(pkgsettings.get("USE_EXPAND_HIDDEN", "").lower().split())
            self._expand_hidden = frozensets.setdefault(s, s)
            s = pkgsettings.useforce
            self._force = frozensets.setdefault(s, s)
            s = pkgsettings.usemask
            self._mask = frozensets.setdefault(s, s)

        @property
        def expand(self):
            if self._expand is None:
                self._init_force_mask()
            return self._expand

        @property
        def expand_hidden(self):
            if self._expand_hidden is None:
                self._init_force_mask()
            return self._expand_hidden

        @property
        def force(self):
            if self._force is None:
                self._init_force_mask()
            return self._force

        @property
        def mask(self):
            if self._mask is None:
                self._init_force_mask()
            return self._mask

    @property
    def repo(self):
        return self._metadata["repository"]

    @property
    def repo_priority(self):
        repo_info = self.root_config.settings.repositories.prepos.get(self.repo)
        if repo_info is None:
            return None
        return repo_info.priority

    @property
    def use(self):
        if self._use is None:
            self._init_use()
        return self._use

    def _get_pkgsettings(self):
        pkgsettings = self.root_config.trees["porttree"].dbapi.doebuild_settings
        pkgsettings.setcpv(self)
        return pkgsettings

    def _init_use(self):
        if self.built:
            # Use IUSE to validate USE settings for built packages,
            # in case the package manager that built this package
            # failed to do that for some reason (or in case of
            # data corruption). The enabled flags must be consistent
            # with implicit IUSE, in order to avoid potential
            # inconsistencies in USE dep matching (see bug #453400).
            use_str = self._metadata["USE"]
            is_valid_flag = self.iuse.is_valid_flag
            enabled_flags = [x for x in use_str.split() if is_valid_flag(x)]
            use_str = " ".join(enabled_flags)
            self._use = self._use_class(self, enabled_flags)
        else:
            try:
                use_str = _PackageMetadataWrapperBase.__getitem__(self._metadata, "USE")
            except KeyError:
                use_str = None
            calculated_use = False
            if not use_str:
                use_str = self._get_pkgsettings()["PORTAGE_USE"]
                calculated_use = True
            self._use = self._use_class(self, use_str.split())
            # Initialize these now, since USE access has just triggered
            # setcpv, and we want to cache the result of the force/mask
            # calculations that were done.
            if calculated_use:
                self._use._init_force_mask()

        _PackageMetadataWrapperBase.__setitem__(self._metadata, "USE", use_str)

        return use_str

    class _iuse:

        __slots__ = (
            "__weakref__",
            "_iuse_implicit_match",
            "_pkg",
            "alias_mapping",
            "all",
            "all_aliases",
            "enabled",
            "disabled",
            "tokens",
        )

        def __init__(self, pkg, tokens, iuse_implicit_match, aliases, eapi):
            self._pkg = pkg
            self.tokens = tuple(tokens)
            self._iuse_implicit_match = iuse_implicit_match
            enabled = []
            disabled = []
            other = []
            enabled_aliases = []
            disabled_aliases = []
            other_aliases = []
            aliases_supported = eapi_has_use_aliases(eapi)
            self.alias_mapping = {}
            for x in tokens:
                prefix = x[:1]
                if prefix == "+":
                    enabled.append(x[1:])
                    if aliases_supported:
                        self.alias_mapping[x[1:]] = aliases.get(x[1:], [])
                        enabled_aliases.extend(self.alias_mapping[x[1:]])
                elif prefix == "-":
                    disabled.append(x[1:])
                    if aliases_supported:
                        self.alias_mapping[x[1:]] = aliases.get(x[1:], [])
                        disabled_aliases.extend(self.alias_mapping[x[1:]])
                else:
                    other.append(x)
                    if aliases_supported:
                        self.alias_mapping[x] = aliases.get(x, [])
                        other_aliases.extend(self.alias_mapping[x])
            self.enabled = frozenset(chain(enabled, enabled_aliases))
            self.disabled = frozenset(chain(disabled, disabled_aliases))
            self.all = frozenset(chain(enabled, disabled, other))
            self.all_aliases = frozenset(
                chain(enabled_aliases, disabled_aliases, other_aliases)
            )

        def is_valid_flag(self, flags):
            """
            @return: True if all flags are valid USE values which may
                    be specified in USE dependencies, False otherwise.
            """
            if isinstance(flags, str):
                flags = [flags]

            for flag in flags:
                if (
                    not flag in self.all
                    and not flag in self.all_aliases
                    and not self._iuse_implicit_match(flag)
                ):
                    return False
            return True

        def get_missing_iuse(self, flags):
            """
            @return: A list of flags missing from IUSE.
            """
            if isinstance(flags, str):
                flags = [flags]
            missing_iuse = []
            for flag in flags:
                if (
                    not flag in self.all
                    and not flag in self.all_aliases
                    and not self._iuse_implicit_match(flag)
                ):
                    missing_iuse.append(flag)
            return missing_iuse

        def get_real_flag(self, flag):
            """
            Returns the flag's name within the scope of this package
            (accounting for aliases), or None if the flag is unknown.
            """
            if flag in self.all:
                return flag

            if flag in self.all_aliases:
                for k, v in self.alias_mapping.items():
                    if flag in v:
                        return k

            if self._iuse_implicit_match(flag):
                return flag

            return None

    def __len__(self):
        return 4

    def __iter__(self):
        """
        This is used to generate mtimedb resume mergelist entries, so we
        limit it to 4 items for backward compatibility.
        """
        return iter(self._hash_key[:4])

    def __lt__(self, other):
        if other.cp != self.cp:
            return self.cp < other.cp
        result = portage.vercmp(self.version, other.version)
        if result < 0:
            return True
        if result == 0 and self.built and other.built:
            return self.build_time < other.build_time
        return False

    def __le__(self, other):
        if other.cp != self.cp:
            return self.cp <= other.cp
        result = portage.vercmp(self.version, other.version)
        if result <= 0:
            return True
        if result == 0 and self.built and other.built:
            return self.build_time <= other.build_time
        return False

    def __gt__(self, other):
        if other.cp != self.cp:
            return self.cp > other.cp
        result = portage.vercmp(self.version, other.version)
        if result > 0:
            return True
        if result == 0 and self.built and other.built:
            return self.build_time > other.build_time
        return False

    def __ge__(self, other):
        if other.cp != self.cp:
            return self.cp >= other.cp
        result = portage.vercmp(self.version, other.version)
        if result >= 0:
            return True
        if result == 0 and self.built and other.built:
            return self.build_time >= other.build_time
        return False

    def with_use(self, use):
        """
        Return an Package instance with the specified USE flags. The
        current instance may be returned if it has identical USE flags.
        @param use: a set of USE flags
        @type use: frozenset
        @return: A package with the specified USE flags
        @rtype: Package
        """
        if use is not self.use.enabled:
            pkg = self.copy()
            pkg._metadata["USE"] = " ".join(use)
        else:
            pkg = self
        return pkg


_all_metadata_keys = set(x for x in portage.auxdbkeys)
_all_metadata_keys.update(Package.metadata_keys)
_all_metadata_keys = frozenset(_all_metadata_keys)

_PackageMetadataWrapperBase = slot_dict_class(_all_metadata_keys)


class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
    """
    Detect metadata updates and synchronize Package attributes.
    """

    __slots__ = ("_pkg",)
    _wrapped_keys = frozenset(["COUNTER", "INHERITED", "USE", "_mtime_"])
    _use_conditional_keys = frozenset(
        [
            "LICENSE",
            "PROPERTIES",
            "RESTRICT",
        ]
    )

    def __init__(self, pkg, metadata):
        _PackageMetadataWrapperBase.__init__(self)
        self._pkg = pkg
        if not pkg.built:
            # USE is lazy, but we want it to show up in self.keys().
            _PackageMetadataWrapperBase.__setitem__(self, "USE", "")

        self.update(metadata)

    def __getitem__(self, k):
        v = _PackageMetadataWrapperBase.__getitem__(self, k)
        if k in self._use_conditional_keys:
            if self._pkg.root_config.settings.local_config and "?" in v:
                try:
                    v = paren_enclose(
                        use_reduce(
                            v,
                            uselist=self._pkg.use.enabled,
                            is_valid_flag=self._pkg.iuse.is_valid_flag,
                        )
                    )
                except InvalidDependString:
                    # This error should already have been registered via
                    # self._pkg._invalid_metadata().
                    pass
                else:
                    self[k] = v

        elif k == "USE" and not self._pkg.built:
            if not v:
                # This is lazy because it's expensive.
                v = self._pkg._init_use()

        return v

    def __setitem__(self, k, v):
        _PackageMetadataWrapperBase.__setitem__(self, k, v)
        if k in self._wrapped_keys:
            getattr(self, "_set_" + k.lower())(k, v)

    def _set_inherited(self, k, v):
        if isinstance(v, str):
            v = frozenset(v.split())
        self._pkg.inherited = v

    def _set_counter(self, k, v):
        if isinstance(v, str):
            try:
                v = int(v.strip())
            except ValueError:
                v = 0
        self._pkg.counter = v

    def _set_use(self, k, v):
        # Force regeneration of _use attribute
        self._pkg._use = None
        # Use raw metadata to restore USE conditional values
        # to unevaluated state
        raw_metadata = self._pkg._raw_metadata
        for x in self._use_conditional_keys:
            try:
                self[x] = raw_metadata[x]
            except KeyError:
                pass

    def _set__mtime_(self, k, v):
        if isinstance(v, str):
            try:
                v = int(v.strip())
            except ValueError:
                v = 0
        self._pkg.mtime = v

    @property
    def properties(self):
        return self["PROPERTIES"].split()

    @property
    def restrict(self):
        return self["RESTRICT"].split()

    @property
    def defined_phases(self):
        """
        Returns tokens from DEFINED_PHASES metadata if it is defined,
        otherwise returns a tuple containing all possible phases. This
        makes it easy to do containment checks to see if it's safe to
        skip execution of a given phase.
        """
        s = self["DEFINED_PHASES"]
        if s:
            return s.split()
        return EBUILD_PHASES
