#!/usr/bin/python3
"""Exercise installed pip-check-reqs commands with offline distribution fixtures."""
import csv
import importlib.metadata
import os
from pathlib import Path
import subprocess
import tempfile

print('Runtime:', {name: importlib.metadata.version(name) for name in ('pip-check-reqs', 'pip', 'packaging')}, flush=True)
with tempfile.TemporaryDirectory(prefix='pcr-cli-') as directory:
    root = Path(directory)
    site = root / 'site'
    site.mkdir()
    for module, distribution in [('pcr_fixture_used', 'pcr-fixture-used'), ('pcr_fixture_extra', 'pcr-fixture-extra')]:
        package = site / module
        package.mkdir()
        (package / '__init__.py').write_text('VALUE = 1\n')
        metadata = site / (module + '-1.0.dist-info')
        metadata.mkdir()
        (metadata / 'METADATA').write_text(f'Metadata-Version: 2.1\nName: {distribution}\nVersion: 1.0\n')
        (metadata / 'WHEEL').write_text('Wheel-Version: 1.0\nGenerator: Debian CLI fixture\nRoot-Is-Purelib: true\nTag: py3-none-any\n')
        with (metadata / 'RECORD').open('w', newline='') as stream:
            writer = csv.writer(stream)
            for path in [package / '__init__.py', metadata / 'METADATA', metadata / 'WHEEL', metadata / 'RECORD']:
                writer.writerow([str(path.relative_to(site)), '', ''])
    project = root / 'project'
    project.mkdir()
    (project / 'app.py').write_text('import pcr_fixture_used\n')
    requirements = project / 'requirements.txt'
    env = os.environ.copy()
    env.update(PYTHONPATH=str(site), PYTHONNOUSERSITE='1', PIP_NO_INDEX='1', PIP_DISABLE_PIP_VERSION_CHECK='1')
    cases = [
        ('missing-clean', 'pip-missing-reqs', 'pcr-fixture-used\n', ['.'], 0, None),
        ('extra-clean', 'pip-extra-reqs', 'pcr-fixture-used\n', ['.'], 0, None),
        ('missing-detected', 'pip-missing-reqs', '', ['.'], 1, 'dist=pcr-fixture-used'),
        ('extra-detected', 'pip-extra-reqs', 'pcr-fixture-used\npcr-fixture-extra\n', ['.'], 1, 'pcr-fixture-extra in'),
        ('missing-ignore-module', 'pip-missing-reqs', '', ['--ignore-module', 'pcr_fixture_*', '.'], 0, None),
        ('missing-ignore-file', 'pip-missing-reqs', '', ['--ignore-file', 'app.py', '.'], 0, None),
        ('extra-ignore-requirement', 'pip-extra-reqs', 'pcr-fixture-used\npcr-fixture-extra\n', ['--ignore-requirement', 'pcr-fixture-extra', '.'], 0, None),
        ('extra-ignore-file', 'pip-extra-reqs', 'pcr-fixture-used\n', ['--ignore-file', 'app.py', '.'], 1, 'pcr-fixture-used in'),
        ('extra-ignore-module', 'pip-extra-reqs', 'pcr-fixture-used\n', ['--ignore-module', 'pcr_fixture_used', '.'], 1, 'pcr-fixture-used in'),
        ('extra-skip-marker', 'pip-extra-reqs', 'pcr-fixture-used\npcr-fixture-extra; python_version < "2"\n', ['--skip-incompatible', '.'], 0, None),
        ('missing-custom-file', 'pip-missing-reqs', 'pcr-fixture-used\n', ['--requirements-file', 'requirements.txt', '.'], 0, None),
        ('extra-custom-file', 'pip-extra-reqs', 'pcr-fixture-used\n', ['--requirements-file', 'requirements.txt', '.'], 0, None),
        ('missing-usage', 'pip-missing-reqs', '', [], 2, 'no source files or directories specified'),
        ('extra-usage', 'pip-extra-reqs', '', [], 2, 'no source files or directories specified'),
        ('missing-version', 'pip-missing-reqs', '', ['--version'], 0, 'pip-check-reqs 2.5.6'),
        ('extra-version', 'pip-extra-reqs', '', ['--version'], 0, 'pip-check-reqs 2.5.6'),
    ]
    failed = 0
    for label, command, content, args, expected_status, expected_text in cases:
        requirements.write_text(content)
        result = subprocess.run(['/usr/bin/' + command, *args], cwd=project, env=env, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=30)
        passed = result.returncode == expected_status and (expected_text in result.stdout if expected_text else not result.stdout)
        failed += not passed
        print(f'{label}: {"PASS" if passed else "FAIL"} (exit {result.returncode}, expected {expected_status})', flush=True)
        if result.stdout:
            print(result.stdout.rstrip(), flush=True)
    print(f'{len(cases) - failed}/{len(cases)} cases passed', flush=True)
    raise SystemExit(bool(failed))
