use std::io::BufRead;
use std::path::{Path, PathBuf};
use std::process::ExitCode;
use std::sync::Arc;
use std::time::Duration;
use ek_core::main_engine::MainEngine;
use ek_station::{StationConfig, boot, default_kinds};
fn main() -> ExitCode {
let args: Vec<String> = std::env::args().skip(1).collect();
let mut cfg = StationConfig::demo();
let mut ready: Option<PathBuf> = None;
let mut it = args.iter();
while let Some(flag) = it.next() {
match flag.as_str() {
"--from" => match it.next() {
Some(path) => match read_plugin_list(Path::new(path)) {
Ok(list) => cfg.plugins = list,
Err(e) => {
eprintln!("ek-station: --from {path}: {e}");
return ExitCode::from(2);
}
},
None => {
eprintln!("ek-station: --from needs a path");
return ExitCode::from(2);
}
},
"--ready-file" => match it.next() {
Some(path) => ready = Some(PathBuf::from(path)),
None => {
eprintln!("ek-station: --ready-file needs a path");
return ExitCode::from(2);
}
},
other => {
eprintln!("ek-station: unknown flag {other} (use --from/--ready-file)");
return ExitCode::from(2);
}
}
}
let engine = Arc::new(MainEngine::new(None));
let kinds = default_kinds();
if let Err(e) = boot(&engine, &kinds, &cfg) {
eprintln!("ek-station: boot failed: {e}");
return ExitCode::from(1);
}
if let Err(e) = engine.start() {
eprintln!("ek-station: start failed: {e:?}");
engine.close_all(Duration::from_secs(3)); return ExitCode::from(1);
}
let names = engine.plugin_names();
eprintln!("ek-station: running (plugins: {})", names.join(", "));
if let Some(path) = ready {
if let Err(e) = std::fs::write(path, "ready\n") {
eprintln!("ek-station: --ready-file write failed: {e:?}");
}
}
let stdin = std::io::stdin();
let mut line = String::new();
let mut graceful = false;
loop {
line.clear();
match stdin.lock().read_line(&mut line) {
Ok(0) => break, Ok(_) => {
let t = line.trim();
if t == "q" || t == "quit" {
graceful = true;
break;
}
}
Err(_) => break,
}
}
if graceful {
engine.close_all(Duration::from_secs(3));
eprintln!("ek-station: closed");
ExitCode::SUCCESS
} else {
eprintln!("ek-station: stdin unavailable; keep-alive loop");
loop {
std::thread::sleep(Duration::from_secs(60));
}
}
}
fn read_plugin_list(path: &Path) -> Result<Vec<String>, String> {
ek_station::pickfile::read(path).map_err(|e| e.to_string())
}