"""Tests for stale coverage detection."""

from datetime import datetime, timedelta, timezone

from app.models.enums import TechniqueStatus, TestState
from app.models.technique import Technique
from app.models.test import Test
from app.services.stale_detection_service import STALE_THRESHOLD_DAYS, detect_stale_coverage


def _technique(db, *, mitre_id="T1059", status=TechniqueStatus.validated):
    tech = Technique(
        mitre_id=mitre_id,
        name="Command and Scripting Interpreter",
        tactic="execution",
        status_global=status,
        review_required=False,
    )
    db.add(tech)
    db.commit()
    db.refresh(tech)
    return tech


def _validated_test(db, technique, *, days_ago: int):
    validated_at = datetime.now(timezone.utc) - timedelta(days=days_ago)
    test = Test(
        technique_id=technique.id,
        name="Coverage test",
        state=TestState.validated,
        red_validated_at=validated_at,
        blue_validated_at=validated_at,
        created_at=validated_at,
    )
    db.add(test)
    db.commit()
    return test


def test_stale_technique_flagged_after_threshold(db):
    tech = _technique(db)
    _validated_test(db, tech, days_ago=STALE_THRESHOLD_DAYS + 30)

    count = detect_stale_coverage(db)

    db.refresh(tech)
    assert count == 1
    assert tech.review_required is True


def test_recent_validated_technique_not_flagged(db):
    tech = _technique(db)
    _validated_test(db, tech, days_ago=30)

    count = detect_stale_coverage(db)

    db.refresh(tech)
    assert count == 0
    assert tech.review_required is False


def test_not_evaluated_never_tested_not_flagged(db):
    tech = _technique(db, status=TechniqueStatus.not_evaluated)

    count = detect_stale_coverage(db)

    db.refresh(tech)
    assert count == 0
    assert tech.review_required is False


def test_stale_detection_idempotent(db):
    tech = _technique(db, mitre_id="T1204")
    _validated_test(db, tech, days_ago=STALE_THRESHOLD_DAYS + 60)
    tech.review_required = True
    db.commit()

    assert detect_stale_coverage(db) == 0
