1use std::{
2 path::PathBuf,
3 sync::{Arc, LazyLock},
4};
5
6use clap::{Parser, Subcommand};
7use haste_fhir_operation_error::OperationOutcomeError;
8use haste_server::auth_n::oidc::routes::discovery::WellKnownDiscoveryDocument;
9use tokio::sync::Mutex;
10
11use crate::commands::config::{CLIConfiguration, load_config};
12
13mod client;
14mod commands;
15
16#[derive(Parser)]
17#[command(version, about, long_about = None)] struct Cli {
19 #[command(subcommand)]
20 command: CLICommand,
21}
22
23#[derive(Subcommand)]
24enum CLICommand {
25 FHIRPath {
27 fhirpath: String,
29 },
30 Generate {
31 #[command(subcommand)]
33 command: commands::codegen::CodeGen,
34 },
35 Server {
36 #[command(subcommand)]
37 command: commands::server::ServerCommands,
38 },
39 Api {
40 #[command(subcommand)]
41 command: commands::api::ApiCommands,
42 },
43 Config {
44 #[command(subcommand)]
45 command: commands::config::ConfigCommands,
46 },
47 Worker {},
48 Testscript {
49 #[command(subcommand)]
50 command: commands::testscript::TestScriptCommands,
51 },
52 Admin {
53 #[command(subcommand)]
54 command: commands::admin::AdminCommands,
55 },
56}
57
58static CONFIG_LOCATION: LazyLock<PathBuf> = LazyLock::new(|| {
59 let config_dir = std::env::home_dir()
60 .unwrap_or_else(|| std::path::PathBuf::from("."))
61 .join(".haste_health");
62
63 std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
64
65 config_dir.join("config.toml")
66});
67
68pub struct CLIState {
69 config: CLIConfiguration,
70 access_token: Option<String>,
71 well_known_document: Option<WellKnownDiscoveryDocument>,
72}
73
74impl CLIState {
75 pub fn new(config: CLIConfiguration) -> Self {
76 CLIState {
77 config,
78 access_token: None,
79 well_known_document: None,
80 }
81 }
82}
83
84static CLI_STATE: LazyLock<Arc<Mutex<CLIState>>> = LazyLock::new(|| {
85 let config = load_config(&CONFIG_LOCATION);
86
87 Arc::new(Mutex::new(CLIState::new(config)))
88});
89
90#[tokio::main]
91async fn main() -> Result<(), OperationOutcomeError> {
92 tracing_subscriber::fmt::init();
96 let cli = Cli::parse();
97 let config = CLI_STATE.clone();
98
99 match &cli.command {
100 CLICommand::FHIRPath { fhirpath } => commands::fhirpath::fhirpath(fhirpath).await,
101 CLICommand::Generate { command } => commands::codegen::codegen(command).await,
102 CLICommand::Server { command } => commands::server::server(command).await,
103 CLICommand::Worker {} => commands::worker::worker().await,
104 CLICommand::Config { command } => commands::config::config(&config, command).await,
105 CLICommand::Api { command } => commands::api::api_commands(config, command).await,
106 CLICommand::Testscript { command } => {
107 commands::testscript::testscript_commands(config, command).await
108 }
109 CLICommand::Admin { command } => commands::admin::admin(command).await,
110 }
111}