import itertools
import logging
import os
import posixpath
import urllib.parse
from typing import List

from pip._vendor.packaging.utils import canonicalize_name

from pip._internal.models.index import PyPI
from pip._internal.utils.compat import has_tls
from pip._internal.utils.misc import normalize_path, redact_auth_from_url

logger = logging.getLogger(__name__)


class SearchScope:

    """
    Encapsulates the locations that pip is configured to search.
    """

    __slots__ = ["find_links", "index_urls"]

    @classmethod
    def create(
        cls,
        find_links: List[str],
        index_urls: List[str],
    ) -> "SearchScope":
        """
        Create a SearchScope object after normalizing the `find_links`.
        """
        # Build find_links. If an argument starts with ~, it may be
        # a local file relative to a home directory. So try normalizing
        # it and if it exists, use the normalized version.
        # This is deliberately conservative - it might be fine just to
        # blindly normalize anything starting with a ~...
        built_find_links: List[str] = []
        for link in find_links:
            if link.startswith("~"):
                new_link = normalize_path(link)
                if os.path.exists(new_link):
                    link = new_link
            built_find_links.append(link)

        # If we don't have TLS enabled, then WARN if anyplace we're looking
        # relies on TLS.
        if not has_tls():
            for link in itertools.chain(index_urls, built_find_links):
                parsed = urllib.parse.urlparse(link)
                if parsed.scheme == "https":
                    logger.warning(
                        "pip is configured with locations that require "
                        "TLS/SSL, however the ssl module in Python is not "
                        "available."
                    )
                    break

        return cls(
            find_links=built_find_links,
            index_urls=index_urls,
        )

    def __init__(
        self,
        find_links: List[str],
        index_urls: List[str],
    ) -> None:
        self.find_links = find_links
        self.index_urls = index_urls

    def get_formatted_locations(self) -> str:
        lines = []
        redacted_index_urls = []
        if self.index_urls and self.index_urls != [PyPI.simple_url]:
            for url in self.index_urls:

                redacted_index_url = redact_auth_from_url(url)

                # Parse the URL
                purl = urllib.parse.urlsplit(redacted_index_url)

                # URL is generally invalid if scheme and netloc is missing
                # there are issues with Python and URL parsing, so this test
                # is a bit crude. See bpo-20271, bpo-23505. Python doesn't
                # always parse invalid URLs correctly - it should raise
                # exceptions for malformed URLs
                if not purl.scheme and not purl.netloc:
                    logger.warning(
                        'The index url "%s" seems invalid, please provide a scheme.',
                        redacted_index_url,
                    )

                redacted_index_urls.append(redacted_index_url)

            lines.append(
                "Looking in indexes: {}".format(", ".join(redacted_index_urls))
            )

        if self.find_links:
            lines.append(
                "Looking in links: {}".format(
                    ", ".join(redact_auth_from_url(url) for url in self.find_links)
                )
            )
        return "\n".join(lines)

    def get_index_urls_locations(self, project_name: str) -> List[str]:
        """Returns the locations found via self.index_urls

        Checks the url_name on the main (first in the list) index and
        use this url_name to produce all locations
        """

        def mkurl_pypi_url(url: str) -> str:
            loc = posixpath.join(
                url, urllib.parse.quote(canonicalize_name(project_name))
            )
            # For maximum compatibility with easy_install, ensure the path
            # ends in a trailing slash.  Although this isn't in the spec
            # (and PyPI can handle it without the slash) some other index
            # implementations might break if they relied on easy_install's
            # behavior.
            if not loc.endswith("/"):
                loc = loc + "/"
            return loc

        return [mkurl_pypi_url(url) for url in self.index_urls]
