use std::time::Duration;
use rust_expect::multi::{
GroupBuilder, GroupManager, MultiSessionManager, PatternSelector, SessionGroup,
};
use rust_expect::prelude::*;
#[tokio::main]
#[allow(clippy::too_many_lines)]
async fn main() -> Result<()> {
println!("rust-expect Multi-Session Example");
println!("==================================\n");
println!("1. Managing session groups...");
let mut group = SessionGroup::new("servers");
let web1 = group.add("web-server-1");
let web2 = group.add("web-server-2");
let db1 = group.add("database-1");
println!(
" Created group '{}' with {} sessions",
group.name(),
group.len()
);
println!(" Sessions: web1={web1}, web2={web2}, db1={db1}");
group.set_active(db1, false);
println!(" Active sessions: {}", group.active_count());
println!("\n2. Using GroupBuilder...");
let group = GroupBuilder::new("production")
.timeout(Duration::from_secs(60))
.add("app-server-1")
.add("app-server-2")
.add("cache-server")
.build();
println!(" Built group: {}", group.name());
println!(" Sessions: {}", group.len());
println!("\n3. Managing multiple groups...");
let mut manager = GroupManager::new();
let web_group = manager.create("web");
web_group.add("nginx-1");
web_group.add("nginx-2");
let db_group = manager.create("database");
db_group.add("postgres-primary");
db_group.add("postgres-replica");
println!(" Groups: {:?}", manager.names());
println!(" Total sessions: {}", manager.total_sessions());
println!("\n4. Using PatternSelector...");
let selector = PatternSelector::new()
.session(0, "login:")
.session(0, "password:")
.session(1, "prompt>")
.default_pattern("$");
println!(
" Patterns for session 0: {} patterns",
selector.patterns_for(0).len()
);
println!(
" Patterns for session 1: {} patterns",
selector.patterns_for(1).len()
);
println!(
" Patterns for unknown session: {} patterns",
selector.patterns_for(99).len()
);
println!("\n5. Iterating over sessions...");
let mut group = SessionGroup::new("test-group");
group.add("session-a");
group.add("session-b");
group.add("session-c");
group.for_each(|id, label| {
println!(" Session {id}: {label}");
});
println!("\n6. Running concurrent shell sessions...");
let mut session1 = Session::spawn("/bin/sh", &[]).await?;
let mut session2 = Session::spawn("/bin/sh", &[]).await?;
session1
.expect_timeout(Pattern::shell_prompt(), Duration::from_secs(2))
.await?;
session2
.expect_timeout(Pattern::shell_prompt(), Duration::from_secs(2))
.await?;
println!(" Session 1 PID: {}", session1.pid());
println!(" Session 2 PID: {}", session2.pid());
session1.send_line("echo 'Hello from session 1'").await?;
session2.send_line("echo 'Hello from session 2'").await?;
let m1 = session1.expect("session 1").await?;
let m2 = session2.expect("session 2").await?;
println!(" Session 1 output: {}", m1.matched.trim());
println!(" Session 2 output: {}", m2.matched.trim());
session1.send_line("exit").await?;
session2.send_line("exit").await?;
session1.wait().await?;
session2.wait().await?;
println!("\n7. Using MultiSessionManager for concurrent expect...");
let s1 = Session::spawn("/bin/sh", &[]).await?;
let s2 = Session::spawn("/bin/sh", &[]).await?;
let mut multi_manager: MultiSessionManager<_> = MultiSessionManager::new();
let id1 = multi_manager.add(s1, "shell-1");
let id2 = multi_manager.add(s2, "shell-2");
println!(" Added {} sessions to manager", multi_manager.len());
println!(" Session IDs: {id1}, {id2}");
let label1 = multi_manager.label(id1).await;
let label2 = multi_manager.label(id2).await;
println!(" Labels: {label1:?}, {label2:?}");
let results = multi_manager.expect_all(Pattern::shell_prompt()).await?;
println!(" Got {} prompt responses", results.len());
let send_results = multi_manager.send_all(b"echo 'hello'\n").await;
println!(" Sent to {} sessions", send_results.len());
let first_match = multi_manager.expect_any("hello").await?;
println!(" First session to respond: {}", first_match.session_id);
let _ = multi_manager.send_all(b"exit\n").await;
println!("\nMulti-session examples completed successfully!");
Ok(())
}