from pip._vendor.packaging.utils import canonicalize_name

from pip._internal.exceptions import CommandError
from pip._internal.utils.typing import MYPY_CHECK_RUNNING

if MYPY_CHECK_RUNNING:
    from typing import Optional, Set, FrozenSet


class FormatControl(object):
    """Helper for managing formats from which a package can be installed.
    """

    __slots__ = ["no_binary", "only_binary"]

    def __init__(self, no_binary=None, only_binary=None):
        # type: (Optional[Set[str]], Optional[Set[str]]) -> None
        if no_binary is None:
            no_binary = set()
        if only_binary is None:
            only_binary = set()

        self.no_binary = no_binary
        self.only_binary = only_binary

    def __eq__(self, other):
        # type: (object) -> bool
        if not isinstance(other, self.__class__):
            return NotImplemented

        if self.__slots__ != other.__slots__:
            return False

        return all(
            getattr(self, k) == getattr(other, k)
            for k in self.__slots__
        )

    def __ne__(self, other):
        # type: (object) -> bool
        return not self.__eq__(other)

    def __repr__(self):
        # type: () -> str
        return "{}({}, {})".format(
            self.__class__.__name__,
            self.no_binary,
            self.only_binary
        )

    @staticmethod
    def handle_mutual_excludes(value, target, other):
        # type: (str, Set[str], Set[str]) -> None
        if value.startswith('-'):
            raise CommandError(
                "--no-binary / --only-binary option requires 1 argument."
            )
        new = value.split(',')
        while ':all:' in new:
            other.clear()
            target.clear()
            target.add(':all:')
            del new[:new.index(':all:') + 1]
            # Without a none, we want to discard everything as :all: covers it
            if ':none:' not in new:
                return
        for name in new:
            if name == ':none:':
                target.clear()
                continue
            name = canonicalize_name(name)
            other.discard(name)
            target.add(name)

    def get_allowed_formats(self, canonical_name):
        # type: (str) -> FrozenSet[str]
        result = {"binary", "source"}
        if canonical_name in self.only_binary:
            result.discard('source')
        elif canonical_name in self.no_binary:
            result.discard('binary')
        elif ':all:' in self.only_binary:
            result.discard('source')
        elif ':all:' in self.no_binary:
            result.discard('binary')
        return frozenset(result)

    def disallow_binaries(self):
        # type: () -> None
        self.handle_mutual_excludes(
            ':all:', self.no_binary, self.only_binary,
        )
