"""Tests para set_dod_contract."""

import json
import os

import pytest

from .set_dod_contract import set_dod_contract


def _read(path: str) -> dict:
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def test_escribe_contrato_en_goal_json_existente_y_preserva_otros_campos(tmp_path):
    sid = "sess-existente"
    path = os.path.join(str(tmp_path), f"{sid}.json")
    existing = {
        "goal": "implementar la fase 2",
        "phase": "build",
        "dod": "tests verdes (volatil, lo escribe el hook)",
        "history": [{"turn": 1, "action": "init"}],
        "prompts": ["primer prompt"],
        "emojis": "🚀",
    }
    with open(path, "w", encoding="utf-8") as f:
        json.dump(existing, f)

    res = set_dod_contract(sid, "criterio fijo de aceptacion", status="pending", goals_dir=str(tmp_path))

    assert res["written"] is True
    assert res["session_id"] == sid
    assert res["path"] == path
    assert res["dod_contract"] == "criterio fijo de aceptacion"
    assert res["dod_status"] == "pending"

    data = _read(path)
    # Las dos claves nuevas estan.
    assert data["dod_contract"] == "criterio fijo de aceptacion"
    assert data["dod_status"] == "pending"
    # TODO el resto se preserva intacto.
    assert data["goal"] == "implementar la fase 2"
    assert data["phase"] == "build"
    assert data["dod"] == "tests verdes (volatil, lo escribe el hook)"
    assert data["history"] == [{"turn": 1, "action": "init"}]
    assert data["prompts"] == ["primer prompt"]
    assert data["emojis"] == "🚀"


def test_crea_el_archivo_si_no_existe(tmp_path):
    sid = "sess-nueva"
    path = os.path.join(str(tmp_path), f"{sid}.json")
    assert not os.path.exists(path)

    res = set_dod_contract(sid, "contrato nuevo", goals_dir=str(tmp_path))

    assert os.path.exists(path)
    assert res["dod_status"] == "pending"  # default
    data = _read(path)
    assert data == {"dod_contract": "contrato nuevo", "dod_status": "pending"}


def test_status_invalido_lanza_valueerror_sin_escribir(tmp_path):
    sid = "sess-bad-status"
    path = os.path.join(str(tmp_path), f"{sid}.json")

    with pytest.raises(ValueError):
        set_dod_contract(sid, "un contrato", status="done", goals_dir=str(tmp_path))

    assert not os.path.exists(path)


def test_contract_vacio_lanza_valueerror_sin_escribir(tmp_path):
    sid = "sess-empty"
    path = os.path.join(str(tmp_path), f"{sid}.json")

    with pytest.raises(ValueError):
        set_dod_contract(sid, "", goals_dir=str(tmp_path))
    with pytest.raises(ValueError):
        set_dod_contract(sid, "   ", goals_dir=str(tmp_path))

    assert not os.path.exists(path)


def test_reescribir_actualiza_sin_duplicar(tmp_path):
    sid = "sess-reescribe"
    path = os.path.join(str(tmp_path), f"{sid}.json")

    set_dod_contract(sid, "contrato v1", status="pending", goals_dir=str(tmp_path))
    set_dod_contract(sid, "contrato v2", status="met", goals_dir=str(tmp_path))

    data = _read(path)
    assert data["dod_contract"] == "contrato v2"
    assert data["dod_status"] == "met"
    # Solo dos claves, ninguna duplicada ni residual.
    assert sorted(data.keys()) == ["dod_contract", "dod_status"]
    # El archivo es JSON valido unico (no concatenado).
    raw = open(path, "r", encoding="utf-8").read()
    assert raw.count('"dod_contract"') == 1
    assert raw.count('"dod_status"') == 1
