# SPDX-License-Identifier: AGPL-3.0-only
# Copyright (c) 2026 sol pbc

"""Tests for the think module unified priority system."""

import importlib
import logging


def test_main_runs_with_mocked_prompts(journal_copy, monkeypatch):
    """Test that main() runs pre/post phases and prompts by priority."""
    mod = importlib.import_module("solstone.think.thinking")

    commands_run = []
    prompts_run = False

    def mock_run_command(cmd, day):
        commands_run.append(cmd)
        return True

    def mock_run_bounded_phase(cmd, day, timeout=None):
        commands_run.append(cmd)
        return (True, False)

    def mock_run_queued_command(cmd, day, timeout=600):
        commands_run.append(cmd)
        return True

    def mock_run_daily_prompts(day, verbose, **kwargs):
        nonlocal prompts_run
        prompts_run = True
        return (5, 0, [], set())  # 5 success, 0 failures, no failed names

    monkeypatch.setattr(mod, "run_command", mock_run_command)
    monkeypatch.setattr(mod, "run_bounded_phase", mock_run_bounded_phase)
    monkeypatch.setattr(mod, "run_queued_command", mock_run_queued_command)
    monkeypatch.setattr(mod, "run_daily_prompts", mock_run_daily_prompts)
    monkeypatch.setattr(
        "sys.argv",
        ["sol think", "--day", "20240101", "--refresh", "--verbose"],
    )

    mod.main()

    # Verify pre-phase: sense ran
    assert any(c[0] == "journal" and c[1] == "sense" for c in commands_run)

    # Verify main phase: prompts ran
    assert prompts_run, "run_daily_prompts should have been called"

    # Verify post-phase: indexer rescan ran
    indexer_cmds = [c for c in commands_run if c[0] == "journal" and c[1] == "indexer"]
    assert len(indexer_cmds) >= 1
    assert any("--rescan" in cmd for cmd in indexer_cmds)


def test_main_runs_segment_think_prephase_before_daily_synthesis(
    journal_copy,
    monkeypatch,
):
    """Test segment-think repair runs between sense repair and daily prompts."""
    mod = importlib.import_module("solstone.think.thinking")

    commands_run = []

    def mock_run_command(cmd, day):
        commands_run.append(cmd)
        return True

    def mock_run_bounded_phase(cmd, day, timeout=None):
        commands_run.append(cmd)
        return (True, False)

    def mock_run_queued_command(cmd, day, timeout=600):
        commands_run.append(cmd)
        return True

    def mock_run_daily_prompts(day, verbose, **kwargs):
        commands_run.append(["__daily_synthesis__"])
        return (5, 0, [], set())

    monkeypatch.setattr(mod, "run_command", mock_run_command)
    monkeypatch.setattr(mod, "run_bounded_phase", mock_run_bounded_phase)
    monkeypatch.setattr(mod, "run_queued_command", mock_run_queued_command)
    monkeypatch.setattr(mod, "run_daily_prompts", mock_run_daily_prompts)
    monkeypatch.setattr(
        "sys.argv",
        ["sol think", "--day", "20240101", "--refresh", "--verbose"],
    )

    mod.main()

    sense_index = next(
        i
        for i, cmd in enumerate(commands_run)
        if len(cmd) >= 2 and cmd[:2] == ["journal", "sense"]
    )
    segment_index = next(
        i
        for i, cmd in enumerate(commands_run)
        if len(cmd) >= 4 and cmd[:4] == ["journal", "think", "--segments", "--day"]
    )
    daily_index = commands_run.index(["__daily_synthesis__"])
    indexer_index = next(
        i
        for i, cmd in enumerate(commands_run)
        if len(cmd) >= 2 and cmd[:2] == ["journal", "indexer"] and "--rescan" in cmd
    )

    segment_cmd = commands_run[segment_index]
    assert "--refresh" not in segment_cmd
    assert "-v" in segment_cmd
    assert sense_index < segment_index < daily_index < indexer_index


def test_from_scratch_refreshes_segment_think_prephase(
    journal_copy,
    monkeypatch,
):
    """Test from-scratch daily think refreshes segment-think repair."""
    mod = importlib.import_module("solstone.think.thinking")

    commands_run = []

    def mock_run_command(cmd, day):
        commands_run.append(cmd)
        return True

    def mock_run_bounded_phase(cmd, day, timeout=None):
        commands_run.append(cmd)
        return (True, False)

    def mock_run_queued_command(cmd, day, timeout=600):
        commands_run.append(cmd)
        return True

    def mock_run_daily_prompts(day, verbose, **kwargs):
        commands_run.append(["__daily_synthesis__", kwargs])
        return (5, 0, [], set())

    monkeypatch.setattr(mod, "run_command", mock_run_command)
    monkeypatch.setattr(mod, "run_bounded_phase", mock_run_bounded_phase)
    monkeypatch.setattr(mod, "run_queued_command", mock_run_queued_command)
    monkeypatch.setattr(mod, "run_daily_prompts", mock_run_daily_prompts)
    monkeypatch.setattr(
        "sys.argv",
        ["sol think", "--day", "20240101", "--from-scratch", "--verbose"],
    )

    mod.main()

    segment_cmd = next(
        cmd
        for cmd in commands_run
        if len(cmd) >= 4 and cmd[:4] == ["journal", "think", "--segments", "--day"]
    )
    assert "--refresh" in segment_cmd
    assert "-v" in segment_cmd


def test_segment_think_prephase_failure_is_non_fatal(
    journal_copy,
    monkeypatch,
    caplog,
):
    """Test daily synthesis still runs when segment-think repair fails."""
    mod = importlib.import_module("solstone.think.thinking")

    commands_run = []

    def mock_run_command(cmd, day):
        commands_run.append(cmd)
        return True

    def mock_run_bounded_phase(cmd, day, timeout=None):
        commands_run.append(cmd)
        return (False, False)

    def mock_run_queued_command(cmd, day, timeout=600):
        commands_run.append(cmd)
        return True

    def mock_run_daily_prompts(day, verbose, **kwargs):
        commands_run.append(["__daily_synthesis__"])
        return (5, 0, [], set())

    monkeypatch.setattr(mod, "run_command", mock_run_command)
    monkeypatch.setattr(mod, "run_bounded_phase", mock_run_bounded_phase)
    monkeypatch.setattr(mod, "run_queued_command", mock_run_queued_command)
    monkeypatch.setattr(mod, "run_daily_prompts", mock_run_daily_prompts)
    monkeypatch.setattr(
        "sys.argv",
        ["sol think", "--day", "20240101", "--refresh", "--verbose"],
    )

    caplog.set_level(logging.WARNING)
    mod.main()

    assert ["__daily_synthesis__"] in commands_run
    assert "Segment-think repair failed, continuing anyway" in caplog.text


def test_segment_mode_skips_pre_post_phases(journal_copy, monkeypatch):
    """Test that segment mode skips sense and journal-stats."""
    mod = importlib.import_module("solstone.think.thinking")

    # Create segment directory
    segment_dir = journal_copy / "chronicle" / "20240101" / "default" / "120000_300"
    segment_dir.mkdir(parents=True, exist_ok=True)

    commands_run = []

    def mock_run_command(cmd, day):
        commands_run.append(cmd)
        return True

    def mock_run_queued_command(cmd, day, timeout=600):
        commands_run.append(cmd)
        return True

    def mock_run_segment_sense(day, segment, refresh, verbose, **kwargs):
        return (1, 0, [])

    monkeypatch.setattr(mod, "run_command", mock_run_command)
    monkeypatch.setattr(mod, "run_queued_command", mock_run_queued_command)
    monkeypatch.setattr(mod, "run_segment_sense", mock_run_segment_sense)
    monkeypatch.setattr(
        "sys.argv",
        ["sol think", "--day", "20240101", "--segment", "120000_300"],
    )

    mod.main()

    # Segment mode should NOT run sense or journal-stats
    assert not any(c[1] == "sense" for c in commands_run if len(c) > 1)
    assert not any(c[1] == "journal-stats" for c in commands_run if len(c) > 1)


def test_priority_validation_required():
    """Test that get_talent_configs raises error for scheduled prompts without priority."""
    from solstone.think.talent import get_talent_configs

    # This test verifies the validation exists - actual validation tested in test_utils.py
    # Here we just confirm all existing scheduled prompts have priority
    configs = get_talent_configs(schedule="daily")
    for name, config in configs.items():
        assert "priority" in config, f"Scheduled prompt '{name}' missing priority"
