"""HTTP-level tests for dispute resolution: POST /tests/{id}/resolve-dispute
and the manager notification fired when a test enters 'disputed'.
"""

import uuid

import pytest

from app.models.evidence import Evidence
from app.models.enums import TeamSide


def _add_evidence(db, test_id, team: TeamSide):
    ev = Evidence(
        test_id=uuid.UUID(test_id),
        file_name="proof.txt",
        file_path="s3://bucket/proof.txt",
        sha256_hash="a" * 64,
        team=team,
    )
    db.add(ev)
    db.commit()


@pytest.fixture
def technique(api, auth_headers):
    resp = api(
        "post", "/api/v1/techniques", auth_headers,
        json={"mitre_id": "T1059.200", "name": "Command Line"},
    )
    assert resp.status_code == 201, resp.text
    return resp.json()["id"]


def _reach_disputed(client, db, api, auth_headers, red_tech_headers, red_lead_headers,
                     blue_tech_headers, blue_lead_headers, technique):
    """Drive a fresh test all the way to disputed: red approves, blue rejects."""
    resp = api(
        "post", "/api/v1/tests", auth_headers,
        json={"technique_id": technique, "name": "Dispute test"},
    )
    test_id = resp.json()["id"]

    api("post", f"/api/v1/tests/{test_id}/start-execution", red_tech_headers)
    _add_evidence(db, test_id, TeamSide.red)
    api("post", f"/api/v1/tests/{test_id}/submit-red", red_tech_headers)
    api("post", f"/api/v1/tests/{test_id}/review-red", red_lead_headers, json={"decision": "approve"})

    api("post", f"/api/v1/tests/{test_id}/start-blue-work", blue_tech_headers)
    _add_evidence(db, test_id, TeamSide.blue)
    api("post", f"/api/v1/tests/{test_id}/submit-blue", blue_tech_headers)
    api("post", f"/api/v1/tests/{test_id}/review-blue", blue_lead_headers, json={"decision": "approve"})

    red_vote = api(
        "post", f"/api/v1/tests/{test_id}/validate-red", red_lead_headers,
        json={"red_validation_status": "approved"},
    )
    assert red_vote.status_code == 200, red_vote.text

    blue_vote = api(
        "post", f"/api/v1/tests/{test_id}/validate-blue", blue_lead_headers,
        json={"blue_validation_status": "rejected", "blue_validation_notes": "Detection insufficient"},
    )
    assert blue_vote.status_code == 200, blue_vote.text
    assert blue_vote.json()["state"] == "disputed"

    return test_id


def test_manager_notified_on_dispute(
    client, db, api, auth_headers, red_tech_headers, red_lead_headers,
    blue_tech_headers, blue_lead_headers, manager_headers, manager_user, technique,
):
    _reach_disputed(client, db, api, auth_headers, red_tech_headers, red_lead_headers,
                     blue_tech_headers, blue_lead_headers, technique)

    resp = api("get", "/api/v1/notifications", manager_headers)
    assert resp.status_code == 200
    notifications = resp.json()
    assert any(n["type"] == "validation_disputed" for n in notifications)


def test_resolve_dispute_forbidden_for_non_approver(
    client, db, api, auth_headers, red_tech_headers, red_lead_headers,
    blue_tech_headers, blue_lead_headers, technique,
):
    """Blue Lead rejected (didn't approve) — they cannot flip the vote here."""
    test_id = _reach_disputed(client, db, api, auth_headers, red_tech_headers, red_lead_headers,
                               blue_tech_headers, blue_lead_headers, technique)

    resp = api(
        "post", f"/api/v1/tests/{test_id}/resolve-dispute", blue_lead_headers,
        json={"target_team": "blue"},
    )
    assert resp.status_code == 400


def test_resolve_dispute_routes_to_red_queue(
    client, db, api, auth_headers, red_tech_headers, red_lead_headers,
    blue_tech_headers, blue_lead_headers, technique,
):
    """Red Lead approved; flips to reject and sends it to the Red queue."""
    test_id = _reach_disputed(client, db, api, auth_headers, red_tech_headers, red_lead_headers,
                               blue_tech_headers, blue_lead_headers, technique)

    resp = api(
        "post", f"/api/v1/tests/{test_id}/resolve-dispute", red_lead_headers,
        json={"target_team": "red", "notes": "redo the attack with more detail"},
    )
    assert resp.status_code == 200, resp.text
    body = resp.json()
    assert body["state"] == "red_executing"
    assert body["red_validation_status"] is None
    assert body["blue_validation_status"] is None
