#!/usr/bin/env python
import os
import sys

import coverage  # type: ignore
import django
from django.test.runner import DiscoverRunner


def setup_django():
    """Set up Django test environment.

    Uses config.django.test settings which configures:
    - PostGIS database for GeoDjango support
    - In-memory cache for test isolation
    - Fast password hashing for speed
    """
    # Add the project root directory to Python path
    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0, project_root)

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.django.test")
    django.setup()


class CustomTestRunner(DiscoverRunner):
    def __init__(self, *args, **kwargs):
        self.cov = coverage.Coverage(
            source=[
                "parks",
                "operators",
                "property_owners",
                "location",
                "rides",
                "reviews",
            ],
            omit=[
                "*/migrations/*",
                "*/management/*",
                "*/admin.py",
                "*/apps.py",
                "manage.py",
            ],
        )
        self.cov.start()
        super().__init__(*args, **kwargs)

    def setup_databases(self, **kwargs):
        """Set up databases and ensure content types are created"""
        old_config = super().setup_databases(**kwargs)

        # Create necessary content types
        from django.contrib.contenttypes.models import ContentType

        ContentType.objects.get_or_create(app_label="parks", model="park")

        return old_config

    def run_suite(self, suite, **kwargs):
        results = super().run_suite(suite, **kwargs)
        self.cov.stop()
        self.cov.save()

        # Print coverage report
        print("\nCoverage Report:")
        self.cov.report()

        # Generate HTML coverage report
        html_dir = os.path.join("tests", "coverage_html")
        self.cov.html_report(directory=html_dir)
        print(f"\nDetailed HTML coverage report generated in: {html_dir}")

        return results


def run_tests():
    # Set up Django
    setup_django()

    # Initialize test runner
    test_runner = CustomTestRunner(verbosity=2, interactive=True, keepdb=True)

    # Define test labels for discovery
    test_labels = [
        "parks.tests",
        "operators.tests",
        "property_owners.tests",
        "location.tests",
        "rides.tests",
        "reviews.tests",
    ]

    # Run tests and collect results
    failures = test_runner.run_tests(test_labels)

    return failures


if __name__ == "__main__":
    # Create tests directory if it doesn't exist
    os.makedirs("tests", exist_ok=True)
    os.makedirs(os.path.join("tests", "coverage_html"), exist_ok=True)

    # Run tests and exit with appropriate status code
    failures = run_tests()
    sys.exit(bool(failures))
