import json
import shutil

from poetry.repositories.pypi_repository import PyPiRepository
from poetry.utils._compat import Path


class MockRepository(PyPiRepository):

    JSON_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "json"
    DIST_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "dists"

    def __init__(self, fallback=False):
        super(MockRepository, self).__init__(
            url="http://foo.bar", disable_cache=True, fallback=fallback
        )

    def _get(self, url):
        parts = url.split("/")[1:]
        name = parts[0]
        if len(parts) == 3:
            version = parts[1]
        else:
            version = None

        if not version:
            fixture = self.JSON_FIXTURES / (name + ".json")
        else:
            fixture = self.JSON_FIXTURES / name / (version + ".json")
            if not fixture.exists():
                fixture = self.JSON_FIXTURES / (name + ".json")

        with fixture.open() as f:
            return json.loads(f.read())

    def _download(self, url, dest):
        filename = url.split("/")[-1]

        fixture = self.DIST_FIXTURES / filename

        shutil.copyfile(str(fixture), dest)


def test_find_packages():
    repo = MockRepository()
    packages = repo.find_packages("requests", "^2.18")

    assert len(packages) == 5


def test_find_packages_with_prereleases():
    repo = MockRepository()
    packages = repo.find_packages("toga", ">=0.3.0.dev2")

    assert len(packages) == 7


def test_package():
    repo = MockRepository()

    package = repo.package("requests", "2.18.4")

    assert package.name == "requests"
    assert len(package.requires) == 4
    assert len(package.extras["security"]) == 3
    assert len(package.extras["socks"]) == 2

    win_inet = package.extras["socks"][0]
    assert win_inet.name == "win-inet-pton"
    assert win_inet.python_versions == "~2.7 || ~2.6"
    assert str(win_inet.marker) == (
        'sys_platform == "win32" and (python_version == "2.7" '
        'or python_version == "2.6") and extra == "socks"'
    )


def test_fallback_on_downloading_packages():
    repo = MockRepository(fallback=True)

    package = repo.package("jupyter", "1.0.0")

    assert package.name == "jupyter"
    assert len(package.requires) == 6

    dependency_names = sorted([dep.name for dep in package.requires])
    assert dependency_names == [
        "ipykernel",
        "ipywidgets",
        "jupyter-console",
        "nbconvert",
        "notebook",
        "qtconsole",
    ]


def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found():
    repo = MockRepository(fallback=True)

    package = repo.package("isort", "4.3.4")

    assert package.name == "isort"
    assert len(package.requires) == 1

    dep = package.requires[0]
    assert dep.name == "futures"
    assert dep.python_versions == "~2.7"
