use bucketwarden_auth::OperatorRole;

pub const HELP: &str = r#"BucketWarden operator CLI

Usage:
  bucketwarden --help
  bucketwarden --version
  bucketwarden [--config <path>] [--quiet] [--verbose] <command>
  bucketwarden health [--config <path>]
  bucketwarden readiness [--config <path>]
  bucketwarden diagnostics [--config <path>]
  bucketwarden metrics [--config <path>]
  bucketwarden ops report health [--bucket NAME] [--config <path>]
  bucketwarden ops report config [--bucket NAME] [--config <path>]
  bucketwarden ops report admin-surfaces [--bucket NAME] [--config <path>]
  bucketwarden ops report incident --type KIND [--bucket NAME] [--config <path>]
  bucketwarden ops report evidence-export [--bucket NAME] [--config <path>]
  bucketwarden ui browser manifest|html|css|js
  bucketwarden config validate --config <path>
  bucketwarden audit export [--config <path>]
  bucketwarden replication status [--config <path>]
  bucketwarden s3 serve [--bind ADDR] [--console-bind ADDR] [--config <path>] [--principal P] [--access-key KEY] [--secret-key SECRET] [--storage filesystem|in-memory] [--data-dir PATH] [--in-memory]
  bucketwarden policy explain --principal P --action A --resource R
  bucketwarden policy simulate --principal P --action A --resource R [--dry-run]
  bucketwarden policy analyze
  bucketwarden auth report identity-providers
  bucketwarden auth report credentials
  bucketwarden auth report temporary-credentials
  bucketwarden auth role assign --principal P --role ROLE --scope S
  bucketwarden auth role list --principal P
  bucketwarden auth key rotate --principal P --old OLD --new NEW --secret SECRET
  bucketwarden auth key revoke --principal P --key KEY
  bucketwarden auth key report-leaked --principal P --key KEY
  bucketwarden conformance [target]
  bucketwarden <demo-command>

Operator commands:
  health                         Print runtime health as JSON.
  readiness                      Print readiness probe JSON.
  diagnostics                    Print operator diagnostics JSON.
  metrics                        Print Prometheus-style runtime metrics.
  ops report ...                 Print stable operator/admin report JSON.
  ui browser ...                 Print the governed browser UI manifest and static assets.
  config validate --config PATH  Validate an operator JSON config file.
  audit export                   Print audit evidence JSON lines.
  replication status             Print replication status JSON.
  s3 serve                       Start S3 and browser console HTTP listeners.
  policy explain                 Explain an allow, explicit deny, or implicit deny.
  policy simulate                Dry-run policy evaluation without mutation.
  policy analyze                 Print static policy findings.
  auth report ...                Print identity and credential support reports.
  auth role assign/list          Manage operator role assignments.
  auth key rotate/revoke/leaked  Exercise credential governance workflows.

Compatibility:
  --health                       Alias for `health`.

Global options:
  --config PATH                  Supply the operator config before command dispatch.
  --quiet                        Suppress non-essential default/help output.
  --verbose                      Include CLI diagnostic metadata where supported.
  --version                      Print the BucketWarden CLI version and build identity.

Config JSON:
  {
    "key_id": "local-dev",
    "key_material": "bucketwarden-local-dev-key",
    "clock_epoch_seconds": 0
  }

Configuration precedence:
  1. --config <path>
  2. BUCKETWARDEN_CONFIG environment variable
  3. built-in development defaults
"#;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum OperatorCommand {
    Help,
    Version,
    Global {
        options: GlobalOptions,
        command: Box<OperatorCommand>,
    },
    Health {
        config_path: Option<String>,
    },
    Readiness {
        config_path: Option<String>,
    },
    Diagnostics {
        config_path: Option<String>,
    },
    Metrics {
        config_path: Option<String>,
    },
    OpsReportHealth {
        config_path: Option<String>,
        bucket: Option<String>,
    },
    OpsReportConfig {
        config_path: Option<String>,
        bucket: Option<String>,
    },
    OpsReportAdminSurfaces {
        config_path: Option<String>,
        bucket: Option<String>,
    },
    OpsReportIncident {
        config_path: Option<String>,
        bucket: Option<String>,
        incident_type: String,
    },
    OpsReportEvidenceExport {
        config_path: Option<String>,
        bucket: Option<String>,
    },
    UiBrowserManifest,
    UiBrowserHtml,
    UiBrowserCss,
    UiBrowserJs,
    ConfigValidate {
        config_path: String,
    },
    AuditExport {
        config_path: Option<String>,
    },
    ReplicationStatus {
        config_path: Option<String>,
    },
    S3Serve {
        bind: String,
        console_bind: String,
        config_path: Option<String>,
        principal: String,
        access_key_id: String,
        secret_access_key: String,
        storage: S3ServeStorage,
    },
    PolicyExplain(crate::operator_tooling::PolicyToolArgs),
    PolicySimulate(crate::operator_tooling::PolicyToolArgs),
    PolicyAnalyze,
    AuthReportIdentityProviders,
    AuthReportCredentials,
    AuthReportTemporaryCredentials,
    AuthRoleAssign {
        principal: String,
        role: OperatorRole,
        scope: String,
    },
    AuthRoleList {
        principal: String,
    },
    AuthKeyRotate {
        principal: String,
        old_access_key_id: String,
        new_access_key_id: String,
        secret_access_key: String,
    },
    AuthKeyRevoke {
        principal: String,
        access_key_id: String,
    },
    AuthKeyReportLeaked {
        principal: String,
        access_key_id: String,
    },
    Conformance {
        target: Option<String>,
    },
    Demo(String),
    DefaultStatus,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum S3ServeStorage {
    Filesystem { data_dir: String },
    InMemory,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct GlobalOptions {
    pub quiet: bool,
    pub verbose: u8,
}

#[derive(Clone, serde::Deserialize)]
pub(crate) struct OperatorConfigFile {
    pub key_id: String,
    pub key_material: String,
    #[serde(default)]
    pub clock_epoch_seconds: u64,
}
