use clap::Parser;
use night_fury_daemon_core::cli::make_req;
use night_fury_daemon_core::{client, spawn};
use serde_json::json;
use tail_fin_daemon::cli::{expand_home, Cli, Commands, DaemonCmd, SessionCmd};
use tail_fin_daemon::driver::SiteEntry;
use tail_fin_daemon::handlers::{grok::GrokHandler, sa::SaHandler, twitter::TwitterHandler};
fn register_all_sites() {
tail_fin_daemon::driver::register_sites(vec![
SiteEntry::new(tail_fin_sa::SeekingAlphaSite, |s| {
Box::new(SaHandler::new(s))
}),
SiteEntry::new(tail_fin_twitter::TwitterSite, |s| {
Box::new(TwitterHandler::new(s))
}),
SiteEntry::new(tail_fin_grok::GrokSite, |s| Box::new(GrokHandler::new(s))),
SiteEntry::stateless(tail_fin_reddit::RedditSite),
SiteEntry::stateless(tail_fin_instagram::InstagramSite),
SiteEntry::stateless(tail_fin_xhs::XhsSite),
SiteEntry::stateless(tail_fin_nansen::NansenSite),
SiteEntry::stateless(tail_fin_coupang::CoupangSite),
SiteEntry::stateless(tail_fin_spotify::SpotifySite),
SiteEntry::stateless(tail_fin_youtube::YoutubeSite),
SiteEntry::stateless(tail_fin_bloomberg::BloombergSite),
SiteEntry::stateless(tail_fin_591::FiveNineOneSite),
SiteEntry::stateless(tail_fin_pcc::PccSite),
SiteEntry::stateless(tail_fin_tradingview::TradingViewSite),
]);
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_env("TFD_LOG")
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.with_writer(std::io::stderr)
.init();
let cli = Cli::parse();
let socket = expand_home(&cli.socket);
if let Some(parent) = std::path::Path::new(&socket).parent() {
let _ = std::fs::create_dir_all(parent);
}
match cli.command {
Commands::Daemon { cmd } => match cmd {
DaemonCmd::Start {
idle_timeout,
daemon_idle,
max_sessions,
} => {
register_all_sites();
tail_fin_daemon::server::serve(&socket, idle_timeout, daemon_idle, max_sessions)
.await?;
}
DaemonCmd::Stop => {
let req = make_req("daemon.shutdown", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
DaemonCmd::Status => {
spawn::ensure_daemon(&socket).await?;
let req = make_req("daemon.status", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
},
Commands::Session { cmd } => match cmd {
SessionCmd::Acquire { site, host } => {
spawn::ensure_daemon(&socket).await?;
let req = make_req(
"session.acquire",
None,
json!({"site": site, "host": host, "mode": "acquired"}),
);
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::Release { session_id } => {
spawn::ensure_daemon(&socket).await?;
let req = make_req("session.release", Some(&session_id), json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::List => {
spawn::ensure_daemon(&socket).await?;
let req = make_req("session.list", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::Destroy { session_id } => {
spawn::ensure_daemon(&socket).await?;
let req = make_req("session.destroy", Some(&session_id), json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
},
Commands::Start {
idle_timeout,
daemon_idle,
max_sessions,
detach: _,
} => {
register_all_sites();
tail_fin_daemon::server::serve(&socket, idle_timeout, daemon_idle, max_sessions)
.await?;
}
Commands::Sa { cmd } => {
tail_fin_daemon::dispatch::sa::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
Commands::Twitter { cmd } => {
tail_fin_daemon::dispatch::twitter::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
Commands::Grok { cmd } => {
tail_fin_daemon::dispatch::grok::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
}
Ok(())
}