# retoor <retoor@molodetz.nl>

from devplacepy.services.jobs.isslop.analysis.scoring import (
    CATEGORY_HUMAN_CLEAN,
    CATEGORY_HUMAN_MESSY,
    CATEGORY_SLOP,
    CATEGORY_SOPHISTICATED,
    CATEGORY_UNCERTAIN,
    categorize,
    compose_slop_score,
    grade_for,
)


def test_compose_slop_score_bounds():
    assert compose_slop_score(0.0, 0.0) == 0.0
    assert compose_slop_score(100.0, 100.0) == 100.0
    assert 0.0 <= compose_slop_score(50.0, 50.0) <= 100.0


def test_compose_slop_score_weighs_ai_heavier_than_quality():
    ai_heavy = compose_slop_score(80.0, 20.0)
    quality_heavy = compose_slop_score(20.0, 80.0)
    assert ai_heavy > quality_heavy


def test_grade_for_is_monotonic():
    grades = [grade_for(value) for value in (0.0, 20.0, 40.0, 60.0, 80.0, 100.0)]
    order = "ABCDF"
    positions = [order.index(grade) for grade in grades]
    assert positions == sorted(positions)
    assert grades[0] == "A"
    assert grades[-1] == "F"


def test_categorize_corners():
    assert categorize(95.0, 95.0) == CATEGORY_SLOP
    assert categorize(95.0, 5.0) == CATEGORY_SOPHISTICATED
    assert categorize(5.0, 5.0) == CATEGORY_HUMAN_CLEAN
    assert categorize(5.0, 95.0) == CATEGORY_HUMAN_MESSY
    assert categorize(50.0, 50.0) == CATEGORY_UNCERTAIN


def test_ai_fraction_is_continuous_and_monotonic():
    from devplacepy.services.jobs.isslop.analysis.scoring import ai_fraction

    assert ai_fraction(0.0) == 0.0
    assert ai_fraction(35.0) == 0.0
    assert ai_fraction(50.0) == 0.5
    assert ai_fraction(65.0) == 1.0
    assert ai_fraction(100.0) == 1.0
    samples = [ai_fraction(v) for v in range(30, 71)]
    assert samples == sorted(samples)
    steps = [b - a for a, b in zip(samples, samples[1:])]
    assert max(steps) < 0.06


def test_adjust_for_images_recomputes_grade_consistently():
    from devplacepy.services.jobs.isslop.analysis.scoring import (
        RepoScores,
        adjust_for_images,
        compose_slop_score,
        grade_for,
    )

    scores = RepoScores(
        origin_score=10.0,
        quality_deficit=10.0,
        slop_score=compose_slop_score(2.0, 10.0),
        grade=grade_for(compose_slop_score(2.0, 10.0)),
        category="human-clean",
        human_percent=98.0,
        ai_percent=2.0,
        confidence="medium",
        strong_signal_count=0,
        medium_signal_count=0,
        files_scored=50,
    )
    adjusted = adjust_for_images(scores, 90.0)
    assert adjusted.ai_percent == round(0.75 * 2.0 + 0.25 * 90.0, 1)
    assert adjusted.human_percent == round(100.0 - adjusted.ai_percent, 1)
    assert adjusted.slop_score == compose_slop_score(adjusted.ai_percent, scores.quality_deficit)
    assert adjusted.grade == grade_for(adjusted.slop_score)
