1mod api;
2mod cli;
3mod devices;
4mod forecast;
5mod reporting;
6mod runner;
7mod scenario;
8mod sim;
9mod telemetry;
10
11use api::run_http_server;
12use cli::{parse_args, print_usage};
13use reporting::print_kpi_report;
14use runner::run_scenario;
15use scenario::ScenarioConfig;
16use telemetry::write_telemetry_to_path;
17
18fn main() {
19 let opts = match parse_args() {
20 Ok(opts) => opts,
21 Err(err) => {
22 eprintln!("Error: {err}");
23 print_usage();
24 std::process::exit(2);
25 }
26 };
27
28 let scenario = if let Some(path) = opts.scenario.as_deref() {
29 match ScenarioConfig::from_path(path) {
30 Ok(s) => s,
31 Err(err) => {
32 eprintln!("Error: {err}");
33 std::process::exit(2);
34 }
35 }
36 } else if let Some(preset) = opts.preset.as_deref() {
37 match ScenarioConfig::from_preset(preset) {
38 Ok(s) => s,
39 Err(err) => {
40 eprintln!("Error: {err}");
41 std::process::exit(2);
42 }
43 }
44 } else {
45 ScenarioConfig::default()
46 };
47
48 let result = run_scenario(&scenario, true);
49 if let Some(path) = opts.telemetry_out.as_deref() {
50 if let Err(err) = write_telemetry_to_path(path, &result.telemetry) {
51 eprintln!(
52 "Error: failed to write telemetry CSV to {}: {err}",
53 path.display()
54 );
55 std::process::exit(1);
56 }
57 }
58
59 print_kpi_report(&result.kpis);
60
61 if let Some(bind_addr) = opts.api_bind.as_deref() {
62 if let Err(err) = run_http_server(bind_addr, result.telemetry.clone()) {
63 eprintln!("Error: failed to start HTTP API on {bind_addr}: {err}");
64 std::process::exit(1);
65 }
66 }
67}