//! Health-check provider for `org-gdocs`.
//!
//! Reports on the pieces auth and sync depend on: resolvable config/data
//! directories, a readable configuration, the Google OAuth client secret, and a
//! cached token. Token *expiry* is not checked here — `yup-oauth2` refreshes
//! silently — so a present token is the meaningful signal.

use tftio_cli_common::{DoctorCheck, DoctorChecks, RepoInfo};

use crate::config::{Config, EnvInputs, Paths};

/// Doctor checks provider for the `org-gdocs` tool.
pub struct OrgGdocsDoctor;

impl DoctorChecks for OrgGdocsDoctor {
    fn repo_info() -> RepoInfo {
        RepoInfo::new("tftio-stuff", "tools")
    }

    fn current_version() -> &'static str {
        env!("CARGO_PKG_VERSION")
    }

    fn tool_checks(&self) -> Vec<DoctorCheck> {
        let paths = match Paths::resolve(&EnvInputs::from_env()) {
            Ok(paths) => paths,
            Err(err) => {
                return vec![DoctorCheck::fail("Config paths", err.to_string())];
            }
        };

        let config = match Config::load(&paths) {
            Ok(config) => config,
            Err(err) => {
                return vec![DoctorCheck::fail(
                    "Configuration",
                    format!("could not load {}: {err}", paths.config_file().display()),
                )];
            }
        };

        vec![
            DoctorCheck::pass(format!("Config directory: {}", paths.config_dir.display())),
            credential_check(&config),
            token_check(&config),
        ]
    }
}

/// Report whether the Google OAuth client secret is present.
fn credential_check(config: &Config) -> DoctorCheck {
    if config.credentials_path.exists() {
        DoctorCheck::pass(format!(
            "Google OAuth client secret: {}",
            config.credentials_path.display()
        ))
    } else {
        DoctorCheck::fail(
            "Google OAuth client secret",
            format!(
                "not found at {} (download a Desktop OAuth client from Google Cloud Console; see README)",
                config.credentials_path.display()
            ),
        )
    }
}

/// Report whether an OAuth token has been cached by a prior `auth` run.
fn token_check(config: &Config) -> DoctorCheck {
    if config.token_path.exists() {
        DoctorCheck::pass(format!(
            "OAuth token cached: {}",
            config.token_path.display()
        ))
    } else {
        DoctorCheck::fail(
            "OAuth token",
            format!(
                "no cached token at {} (run `org-gdocs auth`)",
                config.token_path.display()
            ),
        )
    }
}
