"""
Verification Suite for Milestone 1 (PoE2 1-100 Progression & Game Design Matrix Integrity).
Can be used by Worker M1, Reviewers, and Challengers to independently verify:
1. Strict monotonicity across all 100 levels
2. Zero drift between cumulative_exp and delta_exp
3. Mathematical constraints (< 0.1% onboarding, >= 30% soft-wall)
4. Compatibility with GameDesignMatrixService.validate_game_design_integrity()
"""

import math
import pytest

def calculate_canonical_curve():
    delta = {}
    # Seg 1: 1 - 20
    for l in range(1, 21):
        delta[l] = int(500 * (l ** 2.3) + 100 * l)
    # Seg 2: 21 - 40
    base_20 = delta[20]
    for l in range(21, 41):
        step = l - 20
        delta[l] = int(base_20 * ((1 + 0.085 * step) ** 2.4))
    # Seg 3: 41 - 60
    base_40 = delta[40]
    for l in range(41, 61):
        step = l - 40
        delta[l] = int(base_40 * math.exp(0.092 * step))
    # Seg 4: 61 - 80
    base_60 = delta[60]
    k_lin = int(base_60 * 0.12)
    for l in range(61, 81):
        step = l - 60
        delta[l] = int(base_60 + k_lin * step)
    # Seg 5: 81 - 90
    base_80 = delta[80]
    for l in range(81, 91):
        step = l - 80
        delta[l] = int(base_80 * math.exp(0.145 * step))
    # Seg 6: 91 - 99
    base_90 = delta[90]
    for l in range(91, 100):
        step = l - 90
        delta[l] = int(base_90 * math.exp(0.24 * step))
    # Seg 7: 99 -> 100
    sum_1_98 = sum(delta[l] for l in range(1, 99))
    delta[99] = int(0.33 * sum_1_98)
    return delta

def generate_benchmark_rows():
    delta = calculate_canonical_curve()
    rows = []
    running_cum = 0
    for l in range(1, 101):
        cum_exp = running_cum
        if l < 100:
            exp_next = delta[l]
            running_cum += delta[l]
            tgt_exp = running_cum
        else:
            exp_next = 0
            tgt_exp = running_cum + delta[99]

        # Tiered death penalty ratio
        if l <= 60:
            penalty = 0.0
        elif l <= 80:
            penalty = 0.05
        elif l <= 89:
            penalty = 0.10
        elif l <= 99:
            penalty = 0.15
        else:
            penalty = 0.25

        rows.append({
            'level': l,
            'target_exp': tgt_exp,
            'cumulative_exp': cum_exp,
            'exp_to_next_level': exp_next,
            'death_penalty_ratio': penalty
        })
    return rows

def test_onboarding_ratio():
    delta = calculate_canonical_curve()
    sum_1_20 = sum(delta[l] for l in range(1, 21))
    sum_1_99 = sum(delta[l] for l in range(1, 100))
    ratio = sum_1_20 / sum_1_99
    assert ratio < 0.001, f"Onboarding ratio {ratio} >= 0.1%"
    assert math.isclose(ratio, 0.0001357, rel_tol=1e-2)

def test_hardcore_softwall():
    delta = calculate_canonical_curve()
    sum_1_98 = sum(delta[l] for l in range(1, 99))
    ratio_99 = delta[99] / sum_1_98
    assert ratio_99 >= 0.30, f"Delta 99->100 ratio {ratio_99} < 30%"
    assert math.isclose(ratio_99, 0.33, rel_tol=1e-2)

def test_strict_monotonicity():
    rows = generate_benchmark_rows()
    assert len(rows) == 100
    prev_xp = 0
    for r in rows:
        assert r['target_exp'] > prev_xp, f"Non-monotonic at level {r['level']}: {r['target_exp']} <= {prev_xp}"
        prev_xp = r['target_exp']

def test_zero_drift_cumulative_and_delta():
    rows = generate_benchmark_rows()
    for l in range(1, 100):
        r_curr = rows[l - 1]
        r_next = rows[l]
        assert r_next['cumulative_exp'] - r_curr['cumulative_exp'] == r_curr['exp_to_next_level'], \
            f"Drift at level {l}: next_cum - curr_cum != exp_to_next"

def test_boundary_values():
    rows = generate_benchmark_rows()
    # Level 1
    assert rows[0]['level'] == 1
    assert rows[0]['cumulative_exp'] == 0
    assert rows[0]['exp_to_next_level'] == 600
    assert rows[0]['target_exp'] == 600
    assert rows[0]['death_penalty_ratio'] == 0.0

    # Level 100
    assert rows[99]['level'] == 100
    assert rows[99]['cumulative_exp'] == 23925692466
    assert rows[99]['exp_to_next_level'] == 0
    assert rows[99]['target_exp'] > rows[98]['target_exp']
    assert rows[99]['death_penalty_ratio'] == 0.25

if __name__ == '__main__':
    pytest.main([__file__, '-v'])
