"""
═══════════════════════════════════════════════════════════════════════════════
 ARGUS — Fixtures partagées pour les tests pytest
 Fournit des structures mémoire temporaires reproductibles
═══════════════════════════════════════════════════════════════════════════════
"""

import pytest
import yaml
from pathlib import Path
from datetime import datetime, timedelta


# ═══════════════════════════════════════════════════════════════════════════════
#  DATE HELPERS — Génère des dates de test relatives à un point fixe
#  Utiliser une date fixe (pas datetime.now()) rend les tests déterministes
#  et évite les échecs liés au passage du temps (P2-3 resolved en session 8)
# ═══════════════════════════════════════════════════════════════════════════════

REFERENCE_DATE = datetime(2026, 3, 1)


def days_ago(n: int) -> str:
    """Return a YYYY-MM-DD string for n days before REFERENCE_DATE."""
    return (REFERENCE_DATE - timedelta(days=n)).strftime("%Y-%m-%d")


@pytest.fixture
def tmp_project(tmp_path):
    """
    Crée une structure de projet Argus minimale dans un dossier temporaire.
    Retourne le chemin racine du projet.
    """
    root = tmp_path / "argus_test"
    root.mkdir()

    # Fichier persona minimal
    (root / "argus.persona.yaml").write_text(
        "version: '0.2.0'\nlast_updated: '2026-02-15'\n", encoding="utf-8"
    )

    # Structure miroir du vrai projet Argus :
    #   memory/_index.yaml (compteurs centraux)
    #   memory/semantic/ (patterns, heuristiques, tech, ISTQB)
    #   memory/episodic/ (analyses, décisions, incidents, exécutions)
    #   memory/projects/ (profils projet)
    #   memory/relational/ (associations)
    memory = root / "memory"
    memory.mkdir()
    for sub in [
        "episodic/analyses",
        "episodic/decisions",
        "episodic/incidents",
        "episodic/executions",
        "semantic",
        "projects",
        "relational",
    ]:
        (memory / sub).mkdir(parents=True, exist_ok=True)

    # _index.yaml : source de vérité pour les compteurs et les chemins.
    # Tous les scripts de validation comparent l'état réel des fichiers
    # à ces compteurs pour détecter les désynchronisations.
    index_data = {
        "version": "1.0.0",
        "last_updated": "2026-02-15",
        "episodic": {
            "analyses": {"count": 0, "latest": None, "path": "memory/episodic/analyses/"},
            "decisions": {"count": 0, "latest": None, "path": "memory/episodic/decisions/"},
            "incidents": {"count": 0, "latest": None, "path": "memory/episodic/incidents/"},
            "executions": {"count": 0, "latest": None, "path": "memory/episodic/executions/"},
        },
        "semantic": {
            "defect_patterns": {"count": 2, "path": "memory/semantic/defect_patterns.yaml"},
            "testing_heuristics": {"count": 3, "path": "memory/semantic/testing_heuristics.yaml"},
        },
        "projects": {"count": 1, "path": "memory/projects/"},
        "relational": {"path": "memory/relational/associations.yaml"},
        "statistics": {
            "totals": {"episodes": 0, "patterns": 2, "heuristics": 3, "projects": 1},
        },
        "sequences": {
            "analysis": 0,
            "decision": 0,
            "incident": 0,
            "execution": 0,
            "pattern": 2,
            "heuristic": 3,
        },
    }
    _write_yaml(memory / "_index.yaml", index_data)

    # defect_patterns.yaml (2 patterns)
    patterns_data = {
        "metadata": {"total_patterns": 2},
        "patterns": [
            {
                "id": "PAT-NULL-001",
                "name": "Null reference",
                "category": "null_safety",
                "description": "Accessing null values",
            },
            {
                "id": "PAT-ASYNC-001",
                "name": "Race condition",
                "category": "async",
                "description": "Concurrent access issue",
            },
        ],
    }
    _write_yaml(memory / "semantic" / "defect_patterns.yaml", patterns_data)

    # testing_heuristics.yaml (3 heuristics in 2 sections)
    heuristics_data = {
        "metadata": {"total_heuristics": 3},
        "selection": [
            {"id": "HEU-SEL-001", "name": "Changed code first", "condition": "code changed"},
            {"id": "HEU-SEL-002", "name": "Critical path", "condition": "critical path"},
        ],
        "coverage": [
            {"id": "HEU-COV-001", "name": "Branch coverage", "condition": "complex logic"},
        ],
    }
    _write_yaml(memory / "semantic" / "testing_heuristics.yaml", heuristics_data)

    # technology_knowledge.yaml
    tech_data = {"languages": ["Python"], "frameworks": ["pytest"]}
    _write_yaml(memory / "semantic" / "technology_knowledge.yaml", tech_data)

    # istqb_knowledge.yaml
    istqb_data = {"source": "ISTQB Foundation Level v4.0"}
    _write_yaml(memory / "semantic" / "istqb_knowledge.yaml", istqb_data)

    # Projet fichier
    project_data = {
        "identity": {
            "project_id": "testproj",
            "name": "Test Project",
            "first_seen": "2026-02-15",
        }
    }
    _write_yaml(memory / "projects" / "testproj.yaml", project_data)

    # Template (préfixé _template — exclu de tous les compteurs et validations)
    _write_yaml(
        memory / "projects" / "_template_project.yaml",
        {"identity": {"project_id": "placeholder"}},
    )

    # associations.yaml
    _write_yaml(memory / "relational" / "associations.yaml", {"associations": []})

    return root


@pytest.fixture
def tmp_project_with_episodes(tmp_project):
    """Étend tmp_project avec des fichiers épisodiques."""
    memory = tmp_project / "memory"

    analysis_data = {
        "id": "ANL-20260215-001",
        "metadata": {"id": "ANL-20260215-001", "type": "analysis", "title": "First analysis"},
        "project": "testproj",
        "findings": [],
    }
    _write_yaml(
        memory / "episodic" / "analyses" / "2026-02-15_14-30_analysis_ANL-20260215-001.yaml",
        analysis_data,
    )

    # Mettre à jour l'index
    index_path = memory / "_index.yaml"
    index = _load_yaml(index_path)
    index["episodic"]["analyses"]["count"] = 1
    index["episodic"]["analyses"]["latest"] = "ANL-20260215-001"
    index["statistics"]["totals"]["episodes"] = 1
    index["sequences"]["analysis"] = 1
    _write_yaml(index_path, index)

    return tmp_project


def _write_yaml(path: Path, data: dict):
    """Écrit un dict en YAML."""
    path.write_text(
        yaml.dump(data, default_flow_style=False, allow_unicode=True, sort_keys=False),
        encoding="utf-8",
    )


def _load_yaml(path: Path) -> dict:
    """Charge un fichier YAML."""
    return yaml.safe_load(path.read_text(encoding="utf-8"))
