# agent-office/tests/test_sync_evolver_activity.py
import os
import sys
import tempfile
import gc
from datetime import datetime, timezone, timedelta

_fd, _TMP = tempfile.mkstemp(suffix=".db")
os.close(_fd)
os.unlink(_TMP)
os.environ["AGENT_OFFICE_DB_PATH"] = _TMP

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import pytest
from app import db
db.DB_PATH = _TMP


@pytest.fixture(autouse=True)
def fresh_db():
    # Re-patch DB_PATH at the start of every test (cross-file isolation)
    db.DB_PATH = _TMP
    gc.collect()
    if os.path.exists(_TMP):
        os.remove(_TMP)
    db.init_db()
    yield
    gc.collect()
    if os.path.exists(_TMP):
        try:
            os.remove(_TMP)
        except PermissionError:
            pass


def _today_dow_clamped():
    """오늘의 weekday() (일요일=6은 5로 clamp)."""
    KST = timezone(timedelta(hours=9))
    dow = datetime.now(KST).weekday()
    return 5 if dow == 6 else dow


def _fake_status_with_picks(dow_with_picks):
    async def fake():
        return {
            "week_start": "2026-05-18",
            "current_base": [0.2] * 5,
            "trials": [
                {
                    "id": 100 + i,
                    "day_of_week": i,
                    "weight": [0.2] * 5,
                    "source": "perturb",
                    "picks": ([
                        {"id": j, "numbers": [1,2,3,4,5,6], "meta_score": 0.5}
                        for j in range(5)
                    ] if i == dow_with_picks else []),
                }
                for i in range(6)
            ],
        }
    return fake


@pytest.mark.asyncio
async def test_sync_evolver_activity_creates_apply_task(monkeypatch):
    """오늘 trial에 picks가 있으면 evolver_apply task 1개 생성."""
    from app.agents.lotto import LottoAgent
    from app import service_proxy

    dow = _today_dow_clamped()
    monkeypatch.setattr(service_proxy, "lotto_evolver_status", _fake_status_with_picks(dow))

    agent = LottoAgent()
    await agent.sync_evolver_activity()

    apply_tasks = db.get_agent_tasks("lotto", task_type="evolver_apply", days=1)
    assert len(apply_tasks) == 1
    assert apply_tasks[0]["result_data"]["n_picks"] == 5
    assert apply_tasks[0]["input_data"]["day_of_week"] == dow


@pytest.mark.asyncio
async def test_sync_evolver_activity_idempotent(monkeypatch):
    """같은 날 두 번 호출해도 task는 1개만 (멱등)."""
    from app.agents.lotto import LottoAgent
    from app import service_proxy

    dow = _today_dow_clamped()
    monkeypatch.setattr(service_proxy, "lotto_evolver_status", _fake_status_with_picks(dow))

    agent = LottoAgent()
    await agent.sync_evolver_activity()
    await agent.sync_evolver_activity()

    apply_tasks = db.get_agent_tasks("lotto", task_type="evolver_apply", days=1)
    assert len(apply_tasks) == 1


@pytest.mark.asyncio
async def test_sync_evolver_activity_no_picks_no_task(monkeypatch):
    """오늘 trial에 picks가 없으면 task 생성하지 않음."""
    from app.agents.lotto import LottoAgent
    from app import service_proxy

    async def fake_status():
        return {
            "week_start": "2026-05-18",
            "current_base": [0.2] * 5,
            "trials": [
                {"id": 100 + i, "day_of_week": i, "weight": [0.2]*5,
                 "source": "perturb", "picks": []}
                for i in range(6)
            ],
        }
    monkeypatch.setattr(service_proxy, "lotto_evolver_status", fake_status)

    agent = LottoAgent()
    await agent.sync_evolver_activity()

    apply_tasks = db.get_agent_tasks("lotto", task_type="evolver_apply", days=1)
    assert len(apply_tasks) == 0
