import os
import re
import shutil
import subprocess
import sys

import pytest


SETUP_TEMPLATE = '''\
from setuptools import setup

setup(
    name='{name}',
    version='{version}',
    description='{name}',
    packages=['{pkgdirname}'],
    install_requires={pkgdeps},
    entry_points={{
        'console_scripts': [
            '{pkgdirname}={pkgdirname}:main'
        ]
    }}
)
'''

# All packages generated via generate_pip_package will have the functions below
INIT_TEMPLATE = '''\
def main():
    print('This is {name}')

def hello(actor='world'):
    print('Hello {{}}! This is {name}'.format(actor))
'''

HTML_TEMPLATE = '''\
<html>
  <head>
    <title>Links for {name}</title>
  </head>
  <body>
    <a href='{name}-{version}.tar.gz'>{name}-{version}.tar.gz</a><br />
  </body>
</html>
'''


# Creates a simple python source distribution and copies this into a specified
# directory which is to serve as a mock python repository
#
# Args:
#    tmpdir (str): Directory in which the source files will be created
#    pypi (str): Directory serving as a mock python repository
#    name (str): The name of the package to be created
#    version (str): The version of the package to be created
#
# Returns:
#    None
#
def generate_pip_package(tmpdir, pypi, name, version='0.1', dependencies=None):
    if dependencies is None:
        dependencies = []
    # check if package already exists in pypi
    pypi_package = os.path.join(pypi, re.sub('[^0-9a-zA-Z]+', '-', name))
    if os.path.exists(pypi_package):
        return

    # create the package source files in tmpdir resulting in a directory
    # tree resembling the following structure:
    #
    # tmpdir
    # |-- setup.py
    # `-- package
    #     `-- __init__.py
    #
    setup_file = os.path.join(tmpdir, 'setup.py')
    pkgdirname = re.sub('[^0-9a-zA-Z]+', '', name)
    with open(setup_file, 'w') as f:
        f.write(
            SETUP_TEMPLATE.format(
                name=name,
                version=version,
                pkgdirname=pkgdirname,
                pkgdeps=dependencies
            )
        )
    os.chmod(setup_file, 0o755)

    package = os.path.join(tmpdir, pkgdirname)
    os.makedirs(package)

    main_file = os.path.join(package, '__init__.py')
    with open(main_file, 'w') as f:
        f.write(INIT_TEMPLATE.format(name=name))
    os.chmod(main_file, 0o644)

    # Run sdist with a fresh process
    p = subprocess.run([sys.executable, 'setup.py', 'sdist'], cwd=tmpdir)
    assert p.returncode == 0

    # create directory for this package in pypi resulting in a directory
    # tree resembling the following structure:
    #
    # pypi
    # `-- pypi_package
    #     |-- index.html
    #     `-- foo-0.1.tar.gz
    #
    os.makedirs(pypi_package)

    # add an index html page
    index_html = os.path.join(pypi_package, 'index.html')
    with open(index_html, 'w') as f:
        f.write(HTML_TEMPLATE.format(name=name, version=version))

    # copy generated tarfile to pypi package
    dist_dir = os.path.join(tmpdir, 'dist')
    for tar in os.listdir(dist_dir):
        tarpath = os.path.join(dist_dir, tar)
        shutil.copy(tarpath, pypi_package)


@pytest.fixture
def setup_pypi_repo(tmpdir):
    def create_pkgdir(package):
        pkgdirname = re.sub('[^0-9a-zA-Z]+', '', package)
        pkgdir = os.path.join(str(tmpdir), pkgdirname)
        os.makedirs(pkgdir)
        return pkgdir

    def add_packages(packages, pypi_repo):
        for package, dependencies in packages.items():
            pkgdir = create_pkgdir(package)
            generate_pip_package(pkgdir, pypi_repo, package, dependencies=list(dependencies.keys()))
            for dependency, dependency_dependencies in dependencies.items():
                add_packages({dependency: dependency_dependencies}, pypi_repo)

    return add_packages
