"""Exceptions used throughout package"""

from __future__ import absolute_import

from itertools import chain, groupby, repeat

from pip._vendor.six import iteritems

from pip._internal.utils.typing import MYPY_CHECK_RUNNING

if MYPY_CHECK_RUNNING:
    from typing import Any, Optional, List, Dict, Text

    from pip._vendor.pkg_resources import Distribution
    from pip._vendor.requests.models import Response, Request
    from pip._vendor.six import PY3
    from pip._vendor.six.moves import configparser

    from pip._internal.req.req_install import InstallRequirement

    if PY3:
        from hashlib import _Hash
    else:
        from hashlib import _hash as _Hash


class PipError(Exception):
    """Base pip exception"""


class ConfigurationError(PipError):
    """General exception in configuration"""


class InstallationError(PipError):
    """General exception during installation"""


class UninstallationError(PipError):
    """General exception during uninstallation"""


class NoneMetadataError(PipError):
    """
    Raised when accessing "METADATA" or "PKG-INFO" metadata for a
    pip._vendor.pkg_resources.Distribution object and
    `dist.has_metadata('METADATA')` returns True but
    `dist.get_metadata('METADATA')` returns None (and similarly for
    "PKG-INFO").
    """

    def __init__(self, dist, metadata_name):
        # type: (Distribution, str) -> None
        """
        :param dist: A Distribution object.
        :param metadata_name: The name of the metadata being accessed
            (can be "METADATA" or "PKG-INFO").
        """
        self.dist = dist
        self.metadata_name = metadata_name

    def __str__(self):
        # type: () -> str
        # Use `dist` in the error message because its stringification
        # includes more information, like the version and location.
        return (
            'None {} metadata found for distribution: {}'.format(
                self.metadata_name, self.dist,
            )
        )


class DistributionNotFound(InstallationError):
    """Raised when a distribution cannot be found to satisfy a requirement"""


class RequirementsFileParseError(InstallationError):
    """Raised when a general error occurs parsing a requirements file line."""


class BestVersionAlreadyInstalled(PipError):
    """Raised when the most up-to-date version of a package is already
    installed."""


class BadCommand(PipError):
    """Raised when virtualenv or a command is not found"""


class CommandError(PipError):
    """Raised when there is an error in command-line arguments"""


class SubProcessError(PipError):
    """Raised when there is an error raised while executing a
    command in subprocess"""


class PreviousBuildDirError(PipError):
    """Raised when there's a previous conflicting build directory"""


class NetworkConnectionError(PipError):
    """HTTP connection error"""

    def __init__(self, error_msg, response=None, request=None):
        # type: (Text, Response, Request) -> None
        """
        Initialize NetworkConnectionError with  `request` and `response`
        objects.
        """
        self.response = response
        self.request = request
        self.error_msg = error_msg
        if (self.response is not None and not self.request and
                hasattr(response, 'request')):
            self.request = self.response.request
        super(NetworkConnectionError, self).__init__(
            error_msg, response, request)

    def __str__(self):
        # type: () -> str
        return str(self.error_msg)


class InvalidWheelFilename(InstallationError):
    """Invalid wheel filename."""


class UnsupportedWheel(InstallationError):
    """Unsupported wheel."""


class MetadataInconsistent(InstallationError):
    """Built metadata contains inconsistent information.

    This is raised when the metadata contains values (e.g. name and version)
    that do not match the information previously obtained from sdist filename
    or user-supplied ``#egg=`` value.
    """
    def __init__(self, ireq, field, built):
        # type: (InstallRequirement, str, Any) -> None
        self.ireq = ireq
        self.field = field
        self.built = built

    def __str__(self):
        # type: () -> str
        return "Requested {} has different {} in metadata: {!r}".format(
            self.ireq, self.field, self.built,
        )


class HashErrors(InstallationError):
    """Multiple HashError instances rolled into one for reporting"""

    def __init__(self):
        # type: () -> None
        self.errors = []  # type: List[HashError]

    def append(self, error):
        # type: (HashError) -> None
        self.errors.append(error)

    def __str__(self):
        # type: () -> str
        lines = []
        self.errors.sort(key=lambda e: e.order)
        for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__):
            lines.append(cls.head)
            lines.extend(e.body() for e in errors_of_cls)
        if lines:
            return '\n'.join(lines)
        return ''

    def __nonzero__(self):
        # type: () -> bool
        return bool(self.errors)

    def __bool__(self):
        # type: () -> bool
        return self.__nonzero__()


class HashError(InstallationError):
    """
    A failure to verify a package against known-good hashes

    :cvar order: An int sorting hash exception classes by difficulty of
        recovery (lower being harder), so the user doesn't bother fretting
        about unpinned packages when he has deeper issues, like VCS
        dependencies, to deal with. Also keeps error reports in a
        deterministic order.
    :cvar head: A section heading for display above potentially many
        exceptions of this kind
    :ivar req: The InstallRequirement that triggered this error. This is
        pasted on after the exception is instantiated, because it's not
        typically available earlier.

    """
    req = None  # type: Optional[InstallRequirement]
    head = ''
    order = None  # type: Optional[int]

    def body(self):
        # type: () -> str
        """Return a summary of me for display under the heading.

        This default implementation simply prints a description of the
        triggering requirement.

        :param req: The InstallRequirement that provoked this error, with
            its link already populated by the resolver's _populate_link().

        """
        return '    {}'.format(self._requirement_name())

    def __str__(self):
        # type: () -> str
        return '{}\n{}'.format(self.head, self.body())

    def _requirement_name(self):
        # type: () -> str
        """Return a description of the requirement that triggered me.

        This default implementation returns long description of the req, with
        line numbers

        """
        return str(self.req) if self.req else 'unknown package'


class VcsHashUnsupported(HashError):
    """A hash was provided for a version-control-system-based requirement, but
    we don't have a method for hashing those."""

    order = 0
    head = ("Can't verify hashes for these requirements because we don't "
            "have a way to hash version control repositories:")


class DirectoryUrlHashUnsupported(HashError):
    """A hash was provided for a version-control-system-based requirement, but
    we don't have a method for hashing those."""

    order = 1
    head = ("Can't verify hashes for these file:// requirements because they "
            "point to directories:")


class HashMissing(HashError):
    """A hash was needed for a requirement but is absent."""

    order = 2
    head = ('Hashes are required in --require-hashes mode, but they are '
            'missing from some requirements. Here is a list of those '
            'requirements along with the hashes their downloaded archives '
            'actually had. Add lines like these to your requirements files to '
            'prevent tampering. (If you did not enable --require-hashes '
            'manually, note that it turns on automatically when any package '
            'has a hash.)')

    def __init__(self, gotten_hash):
        # type: (str) -> None
        """
        :param gotten_hash: The hash of the (possibly malicious) archive we
            just downloaded
        """
        self.gotten_hash = gotten_hash

    def body(self):
        # type: () -> str
        # Dodge circular import.
        from pip._internal.utils.hashes import FAVORITE_HASH

        package = None
        if self.req:
            # In the case of URL-based requirements, display the original URL
            # seen in the requirements file rather than the package name,
            # so the output can be directly copied into the requirements file.
            package = (self.req.original_link if self.req.original_link
                       # In case someone feeds something downright stupid
                       # to InstallRequirement's constructor.
                       else getattr(self.req, 'req', None))
        return '    {} --hash={}:{}'.format(package or 'unknown package',
                                            FAVORITE_HASH,
                                            self.gotten_hash)


class HashUnpinned(HashError):
    """A requirement had a hash specified but was not pinned to a specific
    version."""

    order = 3
    head = ('In --require-hashes mode, all requirements must have their '
            'versions pinned with ==. These do not:')


class HashMismatch(HashError):
    """
    Distribution file hash values don't match.

    :ivar package_name: The name of the package that triggered the hash
        mismatch. Feel free to write to this after the exception is raise to
        improve its error message.

    """
    order = 4
    head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS '
            'FILE. If you have updated the package versions, please update '
            'the hashes. Otherwise, examine the package contents carefully; '
            'someone may have tampered with them.')

    def __init__(self, allowed, gots):
        # type: (Dict[str, List[str]], Dict[str, _Hash]) -> None
        """
        :param allowed: A dict of algorithm names pointing to lists of allowed
            hex digests
        :param gots: A dict of algorithm names pointing to hashes we
            actually got from the files under suspicion
        """
        self.allowed = allowed
        self.gots = gots

    def body(self):
        # type: () -> str
        return '    {}:\n{}'.format(self._requirement_name(),
                                    self._hash_comparison())

    def _hash_comparison(self):
        # type: () -> str
        """
        Return a comparison of actual and expected hash values.

        Example::

               Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde
                            or 123451234512345123451234512345123451234512345
                    Got        bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef

        """
        def hash_then_or(hash_name):
            # type: (str) -> chain[str]
            # For now, all the decent hashes have 6-char names, so we can get
            # away with hard-coding space literals.
            return chain([hash_name], repeat('    or'))

        lines = []  # type: List[str]
        for hash_name, expecteds in iteritems(self.allowed):
            prefix = hash_then_or(hash_name)
            lines.extend(('        Expected {} {}'.format(next(prefix), e))
                         for e in expecteds)
            lines.append('             Got        {}\n'.format(
                         self.gots[hash_name].hexdigest()))
        return '\n'.join(lines)


class UnsupportedPythonVersion(InstallationError):
    """Unsupported python version according to Requires-Python package
    metadata."""


class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
    """When there are errors while loading a configuration file
    """

    def __init__(self, reason="could not be loaded", fname=None, error=None):
        # type: (str, Optional[str], Optional[configparser.Error]) -> None
        super(ConfigurationFileCouldNotBeLoaded, self).__init__(error)
        self.reason = reason
        self.fname = fname
        self.error = error

    def __str__(self):
        # type: () -> str
        if self.fname is not None:
            message_part = " in {}.".format(self.fname)
        else:
            assert self.error is not None
            message_part = ".\n{}\n".format(self.error)
        return "Configuration file {}{}".format(self.reason, message_part)
