// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use crate::cmds::accounts::get_current_account;
use crate::cmds::logs::{Logs, Sync, print_logs_metadata_table};
use clap::Subcommand;
use ordinary_api::client::OrdinaryApiClient;

#[derive(Subcommand, Debug)]
pub enum Root {
    /// get system and process info for the
    /// Ordinary API server.
    Info,
    /// query system and application logs
    Logs {
        #[command(subcommand)]
        logs: Logs,
    },
    /// lock resources to prevent abuse
    Lock {
        /// account to be locked
        #[arg(short, long)]
        account: String,
    },
    /// unlock resources upon resolution
    Unlock {
        /// account to be unlocked
        #[arg(short, long)]
        account: String,
    },
}

impl Root {
    pub async fn handle(
        &self,
        api_domain: Option<&str>,
        accept_invalid_certs: bool,
        insecure: bool,
    ) -> anyhow::Result<()> {
        let account = get_current_account(insecure)?;
        let client = OrdinaryApiClient::new(
            &account.host,
            &account.name,
            api_domain,
            accept_invalid_certs,
            crate::USER_AGENT,
            false,
        )?;

        match self {
            Self::Info => {
                let api_info = client.root_get_info().await?;
                println!("{}", serde_json::to_string(&api_info)?);
            }
            Self::Logs { logs } => match logs {
                Logs::Search {
                    format,
                    query,
                    limit,
                    sync,
                } => {
                    if sync == &Some(true) {
                        client.root_logs_sync(None, None).await?;
                    }

                    let res = client.root_logs_search(query, format.as_str(), limit)?;

                    print!("{res}");
                }
                Logs::Sync { sync } => match sync {
                    Sync::Info => {
                        let remote_metadata = client.root_logs_remote_metadata().await?;
                        let local_metadata = client.root_logs_local_metadata()?;

                        print_logs_metadata_table(remote_metadata, local_metadata);
                    }
                    Sync::All { force } => {
                        client.root_logs_sync(*force, None).await?;
                    }
                    Sync::File { name } => {
                        client.root_logs_sync(None, Some(name)).await?;
                    }
                },
            },
            Self::Lock { account } => {
                client.root_lock_account(account.as_str()).await?;
            }
            Self::Unlock { account } => {
                client.root_unlock_account(account.as_str()).await?;
            }
        }

        Ok(())
    }
}
