#!/usr/bin/env python3
"""Test to verify no raw SQL is used in the codebase (except in allowed locations)."""

import sys
from pathlib import Path

sys.path.insert(
    0,
    str(Path(__file__).parent.parent.parent.resolve()),
)

import re


def check_file_for_raw_sql(filepath):
    """Check a single file for raw SQL usage."""
    with open(filepath, "r", encoding="utf-8") as f:
        content = f.read()

    # Skip if it's a test file, migration file, or database-specific files
    filepath_str = str(filepath).lower()
    if any(
        skip in filepath_str
        for skip in [
            "test",
            "migration",
            "encrypted_db.py",
            "sqlcipher_utils.py",
            "thread_local_session.py",
            "queue/processor.py",
        ]
    ):
        return []

    violations = []
    lines = content.split("\n")

    # Patterns that indicate raw SQL
    sql_patterns = [
        r"cursor\.execute\s*\(",
        r"conn\.execute\s*\(",
        r'session\.execute\s*\(\s*["\']',
        r'["\']SELECT\s+.*FROM\s+',
        r'["\']INSERT\s+INTO\s+',
        r'["\']UPDATE\s+.*SET\s+',
        r'["\']DELETE\s+FROM\s+',
        r'["\']CREATE\s+TABLE\s+',
        r'["\']DROP\s+TABLE\s+',
        r'["\']ALTER\s+TABLE\s+',
    ]

    # Allowed patterns (SQLCipher PRAGMAs and simple connection tests)
    allowed_patterns = [
        r"PRAGMA\s+(cipher_|quick_check|rekey)",  # SQLCipher pragmas
        r"SELECT\s+1(?:\s|$|;)",  # Simple connection test
        r'text\s*\(\s*["\'](?:SELECT\s+1|PRAGMA)',  # SQLAlchemy text() with allowed queries
    ]

    for line_num, line in enumerate(lines, 1):
        for pattern in sql_patterns:
            if re.search(pattern, line, re.IGNORECASE):
                # Check if it's in a comment or docstring
                stripped = line.strip()
                if (
                    stripped.startswith("#")
                    or stripped.startswith('"""')
                    or stripped.startswith("'''")
                ):
                    continue

                # Check if it's an allowed pattern
                is_allowed = False
                for allowed in allowed_patterns:
                    if re.search(allowed, line, re.IGNORECASE):
                        is_allowed = True
                        break

                if not is_allowed:
                    violations.append((line_num, line.strip()))

    return violations


def test_no_raw_sql_in_src():
    """Test that no raw SQL is used in src directory (except allowed patterns).

    Allowed exceptions:
    - encrypted_db.py file (SQLCipher-specific operations)
    - PRAGMA commands for SQLCipher (cipher_*, quick_check, rekey)
    - Simple connection tests (SELECT 1)
    """
    src_path = Path(__file__).parent.parent.parent / "src"
    violations = {}

    # Walk through all Python files
    for filepath in src_path.rglob("*.py"):
        file_violations = check_file_for_raw_sql(filepath)
        if file_violations:
            violations[str(filepath)] = file_violations

    # Report violations
    if violations:
        print("\n❌ Found raw SQL in the following files:")
        for filepath, file_violations in violations.items():
            print(f"\n{filepath}:")
            for line_num, line in file_violations:
                print(f"  Line {line_num}: {line[:80]}...")

        # This should fail the test
        assert False, f"Found raw SQL in {len(violations)} files"
    else:
        print(
            "✓ No raw SQL found in src directory (excluding allowed patterns)"
        )


def test_orm_imports_used():
    """Test that files are using SQLAlchemy ORM imports."""
    src_path = Path(__file__).parent.parent.parent / "src"
    files_with_db_operations = []
    files_with_orm_imports = []

    for filepath in src_path.rglob("*.py"):
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()

        # Check if file has database operations
        if any(
            pattern in content
            for pattern in [
                "get_db_session",
                "ResearchHistory",
                "ResearchResource",
            ]
        ):
            files_with_db_operations.append(filepath)

            # Check if it has ORM imports
            if any(
                pattern in content
                for pattern in [
                    "from sqlalchemy",
                    "import.*session",
                    ".query(",
                    ".filter",
                ]
            ):
                files_with_orm_imports.append(filepath)

    print(
        f"✓ Found {len(files_with_orm_imports)} files using ORM out of {len(files_with_db_operations)} files with DB operations"
    )


def test_models_imported_from_correct_location():
    """Test that models are imported from the consolidated location."""
    src_path = Path(__file__).parent.parent.parent / "src"
    incorrect_imports = {}

    # Old import patterns that should not be used
    old_patterns = [
        r"from.*web\.models\.database import.*(?:Research|ResearchHistory)",
        r"from.*web\.database\.models import",
        r"from.*benchmarks\.models\.benchmark_models import",
    ]

    for filepath in src_path.rglob("*.py"):
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()

        violations = []
        lines = content.split("\n")

        for line_num, line in enumerate(lines, 1):
            for pattern in old_patterns:
                if re.search(pattern, line):
                    violations.append((line_num, line.strip()))

        if violations:
            incorrect_imports[str(filepath)] = violations

    if incorrect_imports:
        print("\n❌ Found imports from old model locations:")
        for filepath, violations in incorrect_imports.items():
            print(f"\n{filepath}:")
            for line_num, line in violations:
                print(f"  Line {line_num}: {line}")

        # This should fail the test
        assert False, (
            f"Found {len(incorrect_imports)} files with incorrect model imports"
        )
    else:
        print("✓ All models imported from correct location (database.models)")


if __name__ == "__main__":
    test_no_raw_sql_in_src()
    test_orm_imports_used()
    test_models_imported_from_correct_location()
    print("\n✅ All SQL/ORM compliance tests passed!")
