#!/usr/bin/env python3

# Script to run coverage tests for yt-dlp
#
# Usage:
#   python -m devscripts.run_coverage [test_path] [module_path] [additional pytest args]
#
# Examples:
#   python -m devscripts.run_coverage                         # Test everything
#   python -m devscripts.run_coverage test/devscripts         # Test devscripts
#   python -m devscripts.run_coverage test/test_utils.py yt_dlp.utils  # Test specific module
#   python -m devscripts.run_coverage test/test_utils.py "yt_dlp.utils,yt_dlp.YoutubeDL"  # Test multiple modules
#   python -m devscripts.run_coverage test -v                 # With verbosity
#
# Using hatch:
#   hatch run hatch-test:run-cov [args]                       # Same arguments as above
#   hatch test --cover                                        # Run all tests with coverage
#
# Important:
#   - Always run this script from the project root directory
#   - Test paths are relative to the project root
#   - Module paths use Python import syntax (with dots)
#   - Coverage reports are generated in .coverage-reports/

import sys
import subprocess
from pathlib import Path

script_dir = Path(__file__).parent
repo_root = script_dir.parent


def main():
    args = sys.argv[1:]

    if not args:
        # Default to running all tests
        test_path = 'test'
        module_path = 'yt_dlp,devscripts'
    elif len(args) == 1:
        test_path = args[0]
        # Try to guess the module path from the test path
        if test_path.startswith('test/devscripts'):
            module_path = 'devscripts'
        elif test_path.startswith('test/'):
            module_path = 'yt_dlp'
        else:
            module_path = 'yt_dlp,devscripts'
    else:
        test_path = args[0]
        module_path = args[1]

    # Initialize coverage reports directory
    cov_dir = repo_root / '.coverage-reports'
    cov_dir.mkdir(exist_ok=True)
    html_dir = cov_dir / 'html'
    html_dir.mkdir(exist_ok=True)

    # Run pytest with coverage
    cmd = [
        'python', '-m', 'pytest',
        f'--cov={module_path}',
        '--cov-config=.coveragerc',
        '--cov-report=term-missing',
        test_path,
    ]

    if len(args) > 2:
        cmd.extend(args[2:])

    print(f'Running coverage on {test_path} for module(s) {module_path}')
    print(f'Command: {" ".join(cmd)}')

    try:
        result = subprocess.run(cmd, check=True)

        # Generate reports after the test run in parallel
        import concurrent.futures

        def generate_html_report():
            return subprocess.run([
                'python', '-m', 'coverage', 'html',
            ], check=True)

        def generate_xml_report():
            return subprocess.run([
                'python', '-m', 'coverage', 'xml',
            ], check=True)

        with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
            html_future = executor.submit(generate_html_report)
            xml_future = executor.submit(generate_xml_report)
            # Wait for both tasks to complete
            concurrent.futures.wait([html_future, xml_future])

        print(f'\nCoverage reports saved to {cov_dir.as_posix()}')
        print(f'HTML report: open {cov_dir.as_posix()}/html/index.html')
        return result.returncode
    except subprocess.CalledProcessError as e:
        print(f'Error running coverage: {e}')
        return e.returncode


if __name__ == '__main__':
    sys.exit(main())