//! Konsolen-REPL — Headless-Treiber für Tests und Betrieb ohne GPU.
//!
//! Liest Zeilen von stdin, gibt sie an `Session::exec` und druckt die
//! Ausgabe. Befehls- und Dialoglogik liegen in `session`, damit das
//! Fenster-Frontend dieselbe Session ohne Duplikat steuern kann.

use std::io::{self, Write};

use crate::session::{Mode, Session};

pub fn run(mut session: Session, signals_path: &str) {
    println!("wds-Konsole — {} Signale aus {}. `help` für Befehle.",
             session.game.signals.len(), signals_path);

    // Reserviertes `[init]`-Signal: KV-Defaults setzen, bevor Stories laufen.
    for line in session.start() { println!("{line}"); }

    while let Some(input) = read_line(prompt_for(&session.mode)) {
        let r = session.exec(input.trim());
        for line in r.output { println!("{line}"); }
        if r.quit { break; }
    }
}

/// Prompt je nach Zustand: Befehl, Dialog-Weiterblättern oder Choice-Wahl.
fn prompt_for(mode: &Mode) -> &'static str {
    match mode {
        Mode::Dialog(d) if !d.choices.is_empty() => "  wahl> ",
        Mode::Dialog(_)                          => "  [Enter] ",
        Mode::Menu                               => "menü> ",
        Mode::FirstPerson                        => "spiel> ",
        Mode::Free                               => "> ",
    }
}

/// Zeile von stdin lesen; `None` bei EOF (Ctrl-D) oder Lesefehler.
fn read_line(prompt: &str) -> Option<String> {
    print!("{prompt}");
    io::stdout().flush().ok();
    let mut buf = String::new();
    match io::stdin().read_line(&mut buf) {
        Ok(0) | Err(_) => None,
        Ok(_) => Some(buf.trim_end().to_string()),
    }
}
