// ── Regression tests for known bugs ──
//
// Each test reproduces the exact preconditions of a previously-fixed bug
// to prevent it from recurring.

mod helpers;

use cove_cli::sidebar::state;
use cove_cli::tmux;

/// Bug #1: Stale pane ID events from a previous session contaminating state.
/// Fix: purge old events when a new window is created with a recycled pane_id.
#[test]
fn stale_pane_id_on_restart() {
    let dir = tempfile::tempdir().unwrap();

    // Old session left events for pane %3
    helpers::write_event_line(dir.path(), "old-session", "asking", "/project", "%3", 1000);

    // Purge stale events (simulates what happens on new window creation)
    state::purge_events_for_pane_in(dir.path(), "%3");

    // New session should read as empty (Fresh state)
    let latest = state::load_latest_events(dir.path());
    assert!(
        latest.get("%3").is_none(),
        "purged pane should have no state (Fresh)"
    );
}

/// Bug #2: Window index collision with base-index=1.
/// User has `set -g base-index 1` — indexes 1,2,3 instead of 0,1,2.
/// Bug was losing windows because parsing assumed 0-based indexes.
#[test]
fn window_index_base_1() {
    let output = helpers::fake_window_output(&[
        (1, "session-a", true, "/project/a"),
        (2, "session-b", false, "/project/b"),
        (3, "session-c", false, "/project/c"),
    ]);

    let windows = tmux::parse_window_list(&output);

    // All 3 windows must be parsed — none lost to index collision
    assert_eq!(windows.len(), 3);
    assert_eq!(windows[0].index, 1);
    assert_eq!(windows[1].index, 2);
    assert_eq!(windows[2].index, 3);
}

/// Bug #4: Idle event arriving before first user prompt (fresh state flicker).
/// An idle event without a prior working event should not count as "has working event".
#[test]
fn idle_suppressed_before_first_prompt() {
    let dir = tempfile::tempdir().unwrap();

    // Only an idle event exists — no working event ever fired
    helpers::write_event_line(dir.path(), "test-sess", "idle", "/project", "%0", 1000);

    let path = dir.path().join("test-sess.jsonl");
    let content = std::fs::read_to_string(&path).unwrap();
    let has_working = content
        .lines()
        .any(|line| line.contains(r#""state":"working""#));

    assert!(
        !has_working,
        "idle-only session should not have a working event"
    );
}

/// SessionEnd event: "end" state should map to Fresh (catch-all), not Idle.
/// Verifies state_from_str("end") behavior is intentional.
#[test]
fn end_state_not_idle() {
    let state = state::state_from_str("end");
    // "end" is not a recognized state string, so it maps to Fresh (the catch-all).
    // This is intentional — the sidebar treats ended sessions the same as fresh ones
    // until the process detection (pane command = zsh/bash) marks them as Done.
    assert_eq!(state, state::WindowState::Fresh);
    assert_ne!(state, state::WindowState::Idle);
}
