//! Shared test helpers for the watchdog module.

use std::path::Path;

mod limits_tests;
mod orphan_tests;
mod reap_tests;

/// Write a fake session log file with `n` tool-using assistant turn entries.
///
/// Each turn includes a single `tool_use` content block so it counts under
/// the watchdog's tool-only turn filter (story 923). The file is named
/// `{agent_name}-{session_id}.log` to match the real naming convention
/// used by `AgentLogWriter`.
pub(super) fn write_fake_session_log(
    project_root: &Path,
    story_id: &str,
    agent_name: &str,
    session_id: &str,
    n_turns: u64,
) {
    write_fake_mixed_session_log(project_root, story_id, agent_name, session_id, n_turns, 0);
}

/// Write a fake session log with `n_tool` tool-using assistant turns and
/// `n_narration` text-only narration turns (story 923 regression).
///
/// Tool turns contain a `tool_use` content block; narration turns contain
/// only a `text` block. The watchdog's `count_turns_in_log` must report
/// `n_tool` only — narration must not count.
pub(super) fn write_fake_mixed_session_log(
    project_root: &Path,
    story_id: &str,
    agent_name: &str,
    session_id: &str,
    n_tool: u64,
    n_narration: u64,
) {
    let log_dir = project_root.join(".huskies").join("logs").join(story_id);
    std::fs::create_dir_all(&log_dir).unwrap();
    let log_path = log_dir.join(format!("{agent_name}-{session_id}.log"));
    let mut content = String::new();
    for _ in 0..n_tool {
        content.push_str(
            &serde_json::to_string(&serde_json::json!({
                "timestamp": "2026-04-25T00:00:00Z",
                "type": "agent_json",
                "story_id": story_id,
                "agent_name": agent_name,
                "data": {
                    "type": "assistant",
                    "message": {
                        "content": [
                            { "type": "tool_use", "name": "Read", "input": {} }
                        ]
                    }
                }
            }))
            .unwrap(),
        );
        content.push('\n');
    }
    for _ in 0..n_narration {
        content.push_str(
            &serde_json::to_string(&serde_json::json!({
                "timestamp": "2026-04-25T00:00:00Z",
                "type": "agent_json",
                "story_id": story_id,
                "agent_name": agent_name,
                "data": {
                    "type": "assistant",
                    "message": {
                        "content": [
                            { "type": "text", "text": "Now let me read the next file." }
                        ]
                    }
                }
            }))
            .unwrap(),
        );
        content.push('\n');
    }
    std::fs::write(log_path, content).unwrap();
}

/// Write a fake session log containing a `result` event with the given cost.
///
/// Used to test budget enforcement via the watchdog's per-session log
/// reading (not `token_usage.jsonl`).
pub(super) fn write_fake_budget_session_log(
    project_root: &Path,
    story_id: &str,
    agent_name: &str,
    session_id: &str,
    cost_usd: f64,
) {
    let log_dir = project_root.join(".huskies").join("logs").join(story_id);
    std::fs::create_dir_all(&log_dir).unwrap();
    let log_path = log_dir.join(format!("{agent_name}-{session_id}.log"));
    let content = serde_json::to_string(&serde_json::json!({
        "timestamp": "2026-04-25T00:00:00Z",
        "type": "agent_json",
        "story_id": story_id,
        "agent_name": agent_name,
        "data": { "type": "result", "total_cost_usd": cost_usd }
    }))
    .unwrap()
        + "\n";
    std::fs::write(log_path, content).unwrap();
}

/// Write a minimal project.toml with the given agent config.
pub(super) fn write_project_config(project_root: &Path, config_toml: &str) {
    let huskies_dir = project_root.join(".huskies");
    std::fs::create_dir_all(&huskies_dir).unwrap();
    std::fs::write(huskies_dir.join("project.toml"), config_toml).unwrap();
}
