"""Tests for compliance score calculation."""

from apiposture_pro.enterprise.compliance.compliance_score import (
    ComplianceScore,
    PenaltyBreakdown,
    calculate_score,
)


def test_score_no_findings():
    score = calculate_score(0, 0, 0, 0)
    assert score.score == 100


def test_score_two_critical():
    score = calculate_score(critical=2, high=0, medium=0, low=0)
    assert score.score == 40  # 100 - 2*30


def test_score_clamped_to_zero():
    score = calculate_score(critical=10, high=0, medium=0, low=0)
    assert score.score == 0


def test_score_one_of_each():
    score = calculate_score(critical=1, high=1, medium=1, low=1)
    # penalty = 30+20+10+5 = 65 -> score = 35
    assert score.score == 35


def test_score_penalty_breakdown_values():
    score = calculate_score(critical=1, high=2, medium=3, low=4)
    # breakdown stores penalty points per severity
    assert score.penalty_breakdown.critical == 30   # 1 * 30
    assert score.penalty_breakdown.high == 40       # 2 * 20
    assert score.penalty_breakdown.medium == 30     # 3 * 10
    assert score.penalty_breakdown.low == 20        # 4 * 5


def test_score_penalty_breakdown_total():
    score = calculate_score(critical=1, high=1, medium=1, low=1)
    assert score.penalty_breakdown.total == 65  # 30+20+10+5


def test_score_returns_compliance_score_instance():
    result = calculate_score(0, 0, 0, 0)
    assert isinstance(result, ComplianceScore)
    assert isinstance(result.penalty_breakdown, PenaltyBreakdown)


def test_trend_stable_when_no_previous():
    score = calculate_score(0, 0, 0, 0)
    assert score.trend == "stable"


def test_trend_up():
    # previous=70, current=80 => delta=+10 >= 5
    score = calculate_score(0, 1, 0, 0, previous_score=70)
    # score = 100 - 20 = 80, delta = 80 - 70 = +10 -> up
    assert score.trend == "up"


def test_trend_down():
    # previous=90, current=70 => delta=-20 <= -5
    score = calculate_score(0, 1, 1, 0, previous_score=90)
    # score = 100-20-10=70, delta = 70-90 = -20 -> down
    assert score.trend == "down"


def test_trend_stable_small_delta():
    # previous=83, current=80 => delta=-3 < 5 -> stable
    score2 = calculate_score(0, 1, 0, 0, previous_score=83)
    # score = 80, delta = -3 -> stable
    assert score2.trend == "stable"


def test_trend_boundary_up():
    # delta=5 exactly -> up
    score = calculate_score(0, 0, 0, 0, previous_score=95)
    # score=100, delta=+5 -> up
    assert score.trend == "up"


def test_trend_boundary_down():
    # delta=-5 exactly -> down
    score = calculate_score(0, 0, 1, 0, previous_score=95)
    # score=90, delta=-5 -> down
    assert score.trend == "down"


def test_score_only_medium():
    score = calculate_score(critical=0, high=0, medium=2, low=0)
    assert score.score == 80  # 100 - 20


def test_score_only_low():
    score = calculate_score(critical=0, high=0, medium=0, low=4)
    assert score.score == 80  # 100 - 20
