"""
Optimus Research Center - Global Test Configuration (conftest.py)
Guarantees:
1. Formal separation of the 4 SQLite database roles:
   - Role 1 (PROTECTED_CANONICAL_DB): Protected production DB (never opened or modified).
   - Role 2 (CANDIDATE_INITIAL_BASELINE_DB): Candidate laboratory initial baseline DB (copied read-only, never modified).
   - Role 3 (EXPERIMENTAL_TEST_DB): Isolated temporary DB where tests legitimately write experimental records.
   - Role 4 (PORTABLE_CLEAN_INSTALL_DB): Fresh DB initialized inside clean portable package extraction tests.
2. Strict module & bytecode provenance verification (Section 8):
   - Prevents tests executed from a candidate copy from silently importing modules or cached bytecode from production.
"""

import os
import sys
import shutil
import marshal
import tempfile
from pathlib import Path
import pytest

_CANDIDATE_ROOT = Path(__file__).resolve().parent.parent
_PROTECTED_PROD_ROOT = Path(r"C:\xampp\htdocs\centro de investigacion").resolve()
_PROTECTED_TRANSFER_ROOT = Path(r"C:\xampp\htdocs\centro de investigacion\dist\OPTIMUS_TRANSFERENCIA_PC").resolve()

# ---------------------------------------------------------------------------
# 1. Enforce sys.path isolation so candidate tests never import production app/
# ---------------------------------------------------------------------------
if _CANDIDATE_ROOT != _PROTECTED_PROD_ROOT:
    cleaned_sys_path = [str(_CANDIDATE_ROOT)]
    for entry in sys.path:
        if not entry:
            continue
        try:
            rp = Path(entry).resolve()
            # Keep .venv site-packages and stdlib, but block production/transfer project roots
            if rp in (_PROTECTED_PROD_ROOT, _PROTECTED_TRANSFER_ROOT):
                continue
        except Exception:
            pass
        if entry not in cleaned_sys_path:
            cleaned_sys_path.append(entry)
    sys.path[:] = cleaned_sys_path
else:
    if str(_CANDIDATE_ROOT) not in sys.path:
        sys.path.insert(0, str(_CANDIDATE_ROOT))

# ---------------------------------------------------------------------------
# 2. Formal 4-Database Separation Setup
# ---------------------------------------------------------------------------
PROTECTED_CANONICAL_DB_PATH = _PROTECTED_PROD_ROOT / "storage" / "db" / "research_center.db"
CANDIDATE_INITIAL_BASELINE_DB_PATH = _CANDIDATE_ROOT / "storage" / "db" / "research_center.db"

_orig_db = str(CANDIDATE_INITIAL_BASELINE_DB_PATH)
_temp_dir = tempfile.mkdtemp(prefix="orc_isolated_test_")
_isolated_db = os.path.join(_temp_dir, "research_center_test.db")
EXPERIMENTAL_TEST_DB_PATH = Path(_isolated_db)

# Read-only binary copy of candidate initial baseline DB into isolated experimental test DB
if os.path.exists(_orig_db) and os.path.getsize(_orig_db) > 0:
    shutil.copyfile(_orig_db, _isolated_db)

# Bind application settings.db_path and SQLAlchemy engine strictly to EXPERIMENTAL_TEST_DB
os.environ["ORC_TEST_DB_PATH"] = _isolated_db


def assert_candidate_provenance_clean(candidate_root: Path = _CANDIDATE_ROOT) -> dict:
    """
    Verifies that all loaded project modules (app.*, scripts.*, tests.*) and compiled .pyc
    files belong strictly to candidate_root and never to the protected production installation.
    Raises RuntimeError immediately if cross-installation contamination is detected.
    """
    cand_resolved = candidate_root.resolve()
    is_external_candidate = (cand_resolved != _PROTECTED_PROD_ROOT)
    checked_modules = []
    violations = []

    for mod_name, mod_obj in list(sys.modules.items()):
        if mod_obj is None:
            continue
        if mod_name == "app" or mod_name.startswith(("app.", "scripts.", "tests.")):
            mod_file = getattr(mod_obj, "__file__", None)
            if not mod_file:
                continue
            mod_path = Path(mod_file).resolve()
            checked_modules.append((mod_name, str(mod_path)))
            try:
                mod_path.relative_to(cand_resolved)
            except ValueError:
                violations.append(
                    f"Module '{mod_name}' loaded from outside candidate root: {mod_path} (expected inside {cand_resolved})"
                )

    if is_external_candidate:
        for pyc_path in cand_resolved.rglob("*.pyc"):
            # Skip any virtual environment inside candidate if present
            if ".venv" in pyc_path.parts or "venv" in pyc_path.parts:
                continue
            try:
                with open(pyc_path, "rb") as f:
                    f.seek(16)
                    code_obj = marshal.load(f)
                    co_fn = str(getattr(code_obj, "co_filename", ""))
                    if co_fn:
                        co_resolved = Path(co_fn).resolve()
                        try:
                            co_resolved.relative_to(cand_resolved)
                        except ValueError:
                            violations.append(
                                f"Stale bytecode '{pyc_path}' has co_filename pointing outside candidate root: {co_fn}"
                            )
            except Exception:
                pass

    if violations:
        raise RuntimeError("PROVENANCE_CONTAMINATION_DETECTED:\n  - " + "\n  - ".join(violations))

    return {
        "candidate_root": str(cand_resolved),
        "checked_modules_count": len(checked_modules),
        "violations_count": 0,
        "provenance_clean": True
    }


@pytest.fixture(scope="session", autouse=True)
def isolated_test_db_lifecycle():
    """Maintains isolated experimental test database and verifies module provenance before and after session."""
    assert_candidate_provenance_clean(_CANDIDATE_ROOT)
    yield _isolated_db
    assert_candidate_provenance_clean(_CANDIDATE_ROOT)
    try:
        from app.core.database import engine
        engine.dispose()
        shutil.rmtree(_temp_dir, ignore_errors=True)
    except Exception:
        pass
