#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${REPO_ROOT}/lib/jeannie/core.sh"
source "${REPO_ROOT}/lib/jeannie/env.sh"
source "${REPO_ROOT}/lib/jeannie/toolchain.sh"
source "${REPO_ROOT}/lib/jeannie/pimox.sh"
source "${REPO_ROOT}/lib/jeannie/preflight.sh"

print_usage() {
    cat <<'EOF'
Usage: ./jeannie <command> [args]

Base, Inventory, And Planning
  help | -h | --help                         Show this grouped help.
  validate                                   Run repo validation checks.
  inventory-check                            Validate the canonical homelab inventory.
  preflight                                  Run non-mutating infrastructure preflight checks.
  doctor-preapply                            Run deeper pre-apply safety checks.
  plan [all|provisioning|cluster|platform|apps|edge]
                                             Run OpenTofu plans without applying changes.

Build And Bootstrap
  up                                         Deploy the full homelab pipeline.
  deploy-gitea                               Deploy the Debian-hosted Gitea container.
  deploy-heimdall                            Deploy the Debian-hosted Heimdall dashboard.
  deploy-matrix                              Deploy the Matrix homeserver (Synapse + Element + Postgres).
  deploy-omniroute                           Deploy the OmniRoute LLM routing gateway.
  deploy-hermes                              Deploy the Hermes agent (git-install + venv + gateway service).
  bootstrap-gitea-repo                       Ensure the Gitea repo and SSH key wiring exist.
  rpi-services                               Deploy Pi-hole, Unbound, and Uptime Kuma on RPi4.
  ollama-setup                               Install/configure Ollama on the Debian host.
  artifact-cache {status|up|down|instructions}
                                             Manage optional Debian artifact caches.
  blockchain-devnet {status|up|down|logs|rpc}
                                             Manage the local Ethereum Anvil devnet.
  blockchain-test [forge args...]            Run Foundry tests for labs/blockchain.
  blockchain-wallet {instructions|new|address|sign-message}
                                             Practice dev wallet and signing workflows.
  golden-ledger {show|check}                 Show or validate Pimox golden image versions.

Cluster Lifecycle
  rebuild-cluster                            Recreate the cluster through the guarded path.
  stop-cluster                               Stop Kubernetes and worker VMs without destroy.
  start-cluster                              Start Kubernetes and desired worker VMs.
  workers <list|tailnet|start|stop|restart|drain|uncordon|recreate-plan|rebalance>
                                             Manage Pimox/Kubernetes workers.
  move-prometheus-stack-workers              Move monitoring workloads to worker nodes.
  doctor-versions [--all|--details|--verbose|--json]
                                             Check Kubernetes/container tooling versions.

Operator View And Reports
  status [--all|--details|--verbose|--json] Problems-first cascade from host to public URLs.
  status --heal-plan                         Build a guarded self-heal plan from status.
  status --heal                              Dry-run auto-eligible self-heal actions.
  scorecard                                  Compact pass/warn/fail operator scorecard.
  capacity                                   Compact capacity and placement report.
  capacity-advisor                          Decide whether to add VMs or fix placement/resources.
  capacity-limits [namespace]               Recommend requests/limits YAML snippets.
  recover-plan                               Print disaster recovery order and prerequisites.
  recover-power [--dry-run]                  Run or preview post-outage recovery.
  heal {plan|apply}                          Plan/apply guarded self-healing actions.
  incident {list|replay|triage}              Classify incident text and suggest read-only next steps.
  safety-case [--since REF] [PATH...]        Generate risk, blast-radius, test, and rollback case.
  agent-sandbox {check|policy}               Classify proposed commands against agent policy.
  impact [--since REF] [PATH...]             Explain affected lab areas before changes.
  review-last-change [REF]                   Summarize changed files, impact, validation.
  map [--dot]                                Print the homelab dependency map.
  change-journal {list|path}                 Show risky-command journal entries.
  release-snapshot                           Write a pre-change release snapshot.

Observability And GitOps
  grafana-dashboards {list|apply}            List or apply repo-managed Grafana dashboards.
  gitops-status                              Print focused Argo CD health and sync status.
  platform                                   Deploy platform stack only.
  edge                                       Deploy/check the OCI edge stack only.
  promote {plan|validate|rollback APP}       Run canary promotion gates and rollback plan.
  cert-check                                 Check public DNS, TLS, and edge URL health.
  backup-status                              Check backup and restore-drill freshness.
  synthetic-checks                           Run end-to-end service probes.
  resource-budget                            Report Kubernetes resource request/limit gaps.
  route-inventory                            Report routes and Uptime Kuma coverage.
  control-plane {status|taint|untaint|pods}
                                             Keep normal pods off the Debian control plane.
  explain <command>|output                   Explain warnings/errors and fix commands.

Recovery And State
  backup-gitea                               Back up the Debian-hosted Gitea data.
  drill-restore                              Run all restore drills.
  drill-gitea-restore                        Run the Gitea restore drill.
  drill-pihole-restore                       Run the Pi-hole restore drill.
  state-backup                               Back up local OpenTofu state files.

Focused Doctors
  doctor-edge [--all|--details|--verbose|--json]
                                             Diagnose edge routing and public exposure.
  doctor-gitea [--all|--details|--verbose|--json]
                                             Diagnose Gitea local/public access.
  doctor-rpi [--all|--details|--verbose|--json]
                                             Diagnose RPi services and DNS.
  doctor-cluster [--all|--details|--verbose|--json]
                                             Diagnose Kubernetes cluster health.

Access, Secrets, And Policy
  access-audit                               Audit SSH, Gitea, Kubernetes, and Tailscale access.
  kubeconfig-readonly                        Create/check read-only kubeconfig material.
  secrets-init                               Initialize SOPS/age secret tooling.
  secrets-check                              Validate repo-managed secret prerequisites.
  tailnet-policy-check                       Validate Tailscale ACL policy as code.
  fix-debian-docker-root                     Repair Debian Docker root placement.

Apps And Services
  apps                                       Deploy application stack only.
  website-translation-model                  Prepare website translation model support.
  website-ollama-listen                      Configure website Ollama access.
  install-gitea-runner [TOKEN]               Install the Gitea Actions runner.
  openwrt                                    Deploy/check OpenWrt lab config.

Security Learning
  security-scan                              Run the security scan bundle.
  security-prepare                           Prepare defensive security tools.
  security-zap                               Run OWASP ZAP checks.
  security-k8s                               Run Kubernetes security checks.
  security-host                              Run host security checks.
  security-trivy                             Run Trivy scans.
  security-secrets                           Run secret leak checks.
  security-nuclei                            Run Nuclei web checks.
  security-web                               Run web security checks.
  security-logs                              Review security-relevant logs.
  security-runtime                           Check runtime security sensors.
  security-attack-path                       Print prioritized attack-path findings.
  prompt-injection-lab {list|run|show}       Run local prompt-injection defense drills.
  red-blue {plan|run|ledger}                 Run or plan safe red-team/blue-team loop.

AI And Indexing
  ai-index                                   Build the local homelab RAG index.
  ai-check                                   Query/check the local AI index.
  ask [--citations] QUESTION...              Find relevant docs/runbooks/commands.
  ai-evals {list|run|show}                   Run deterministic Jeannie/RAG eval cases.
  ai-scheduler {simulate|recommend NAME}     Simulate AI workload placement policy.
  ai-memory {check}                          Check local RAG index provenance freshness.
  model-observe {prompts|run|report}         Track model behavior over stable prompts.

Destructive
  nuke                                       Guarded cluster state destruction path.
EOF
}

if [[ "${JEANNIE_LIBRARY_MODE:-false}" == "true" ]]; then
    # shellcheck disable=SC2317
    return 0 2>/dev/null || exit 0
fi

case "${1:-}" in
    __up-task)
        up_task "${2:-}"
        ;;
    "" | help | -h | --help)
        print_usage
        ;;
    up)
        record_change_journal "up" "$@"
        up
        ;;
    plan)
        plan_homelab "${2:-all}"
        ;;
    rebuild-cluster)
        record_change_journal "rebuild-cluster" "$@"
        rebuild_cluster
        ;;
    stop-cluster)
        record_change_journal "stop-cluster" "$@"
        stop_cluster
        ;;
    start-cluster)
        record_change_journal "start-cluster" "$@"
        start_cluster
        ;;
    status)
        status_report "${@:2}"
        ;;
    capacity)
        capacity_report "$@"
        ;;
    capacity-advisor)
        capacity_advisor "$@"
        ;;
    capacity-limits)
        capacity_limits "$@"
        ;;
    recover-plan)
        recover_plan
        ;;
    gitops-status)
        gitops_status
        ;;
    platform)
        record_change_journal "platform" "$@"
        require_debian_server "platform"
        jeannie_log_start "platform"
        jeannie_step_plan 1
        run_step "Platform OpenTofu apply" platform_apply
        echo "Log: ${JEANNIE_LOG_FILE}"
        ;;
    edge)
        record_change_journal "edge" "$@"
        edge_apply
        ;;
    promote)
        promote "$@"
        ;;
    cert-check)
        cert_check
        ;;
    release-snapshot)
        record_change_journal "release-snapshot" "$@"
        release_snapshot
        ;;
    backup-status)
        backup_status
        ;;
    synthetic-checks)
        synthetic_checks
        ;;
    resource-budget)
        resource_budget "$@"
        ;;
    control-plane)
        control_plane "$@"
        ;;
    artifact-cache)
        artifact_cache "$@"
        ;;
    blockchain-devnet)
        blockchain_devnet "$@"
        ;;
    blockchain-test)
        blockchain_test "$@"
        ;;
    blockchain-wallet)
        blockchain_wallet "$@"
        ;;
    golden-ledger)
        golden_ledger "$@"
        ;;
    route-inventory)
        route_inventory
        ;;
    explain)
        explain "$@"
        ;;
    recover-power)
        recover_power "$@"
        ;;
    heal)
        heal "$@"
        ;;
    incident)
        incident_commander "$@"
        ;;
    safety-case)
        safety_case "$@"
        ;;
    agent-sandbox)
        agent_sandbox "$@"
        ;;
    scorecard)
        scorecard
        ;;
    grafana-dashboards)
        grafana_dashboards "$@"
        ;;
    workers)
        workers_manage "$@"
        ;;
    change-journal)
        change_journal "$@"
        ;;
    map)
        homelab_map "$@"
        ;;
    validate)
        validate_homelab
        ;;
    access-audit)
        access_audit
        ;;
    kubeconfig-readonly)
        kubeconfig_readonly
        ;;
    apps)
        record_change_journal "apps" "$@"
        require_debian_server "apps"
        jeannie_log_start "apps"
        jeannie_step_plan 1
        run_step "Applications" apps
        echo "Log: ${JEANNIE_LOG_FILE}"
        ;;
    website-translation-model)
        website_translation_model
        ;;
    website-ollama-listen)
        website_ollama_listen
        ;;
    ollama-setup)
        ollama_setup
        ;;
    deploy-gitea)
        record_change_journal "deploy-gitea" "$@"
        deploy_gitea
        ;;
    deploy-heimdall)
        record_change_journal "deploy-heimdall" "$@"
        deploy_heimdall
        ;;
    deploy-matrix)
        record_change_journal "deploy-matrix" "$@"
        deploy_matrix
        ;;
    deploy-omniroute)
        record_change_journal "deploy-omniroute" "$@"
        deploy_omniroute
        ;;
    deploy-hermes)
        record_change_journal "deploy-hermes" "$@"
        deploy_hermes
        ;;
    rpi-services)
        record_change_journal "rpi-services" "$@"
        deploy_rpi_services
        ;;
    bootstrap-gitea-repo)
        bootstrap_gitea_repo
        ;;
    backup-gitea)
        backup_gitea
        ;;
    drill-restore)
        drill_restore
        ;;
    drill-gitea-restore)
        drill_gitea_restore
        ;;
    drill-pihole-restore)
        drill_pihole_restore
        ;;
    install-gitea-runner)
        install_gitea_runner "${2:-}"
        ;;
    move-prometheus-stack-workers)
        move_prometheus_stack_workers
        ;;
    doctor-versions)
        doctor_versions "${@:2}"
        ;;
    doctor-edge)
        doctor_edge "${@:2}"
        ;;
    doctor-gitea)
        doctor_gitea "${@:2}"
        ;;
    doctor-rpi)
        doctor_rpi "${@:2}"
        ;;
    doctor-cluster)
        doctor_cluster "${@:2}"
        ;;
    preflight)
        homelab_preflight \"full\"
        ;;
    doctor-preapply)
        doctor_preapply
        ;;
    inventory-check)
        inventory_check
        ;;
    state-backup)
        backup_tofu_state
        ;;
    fix-debian-docker-root)
        fix_debian_docker_root
        ;;
    secrets-init)
        secrets_init
        ;;
    secrets-check)
        secrets_check
        ;;
    tailnet-policy-check)
        tailnet_policy_check
        ;;
    ai-index)
        ai_index
        ;;
    ai-check)
        ai_check
        ;;
    ask)
        ask_homelab "$@"
        ;;
    ai-evals)
        ai_evals "$@"
        ;;
    ai-scheduler)
        ai_scheduler "$@"
        ;;
    ai-memory)
        ai_memory "$@"
        ;;
    model-observe)
        model_observe "$@"
        ;;
    impact)
        impact "$@"
        ;;
    review-last-change)
        review_last_change "$@"
        ;;
    security-scan)
        security_scan
        ;;
    security-prepare)
        security_prepare
        ;;
    security-zap)
        security_zap
        ;;
    security-k8s)
        security_k8s
        ;;
    security-host)
        security_host
        ;;
    security-trivy)
        security_trivy
        ;;
    security-secrets)
        security_secrets
        ;;
    security-nuclei)
        security_nuclei
        ;;
    security-web)
        security_web
        ;;
    security-logs)
        security_logs
        ;;
    security-runtime)
        security_runtime
        ;;
    security-attack-path)
        security_attack_path "$@"
        ;;
    prompt-injection-lab)
        prompt_injection_lab "$@"
        ;;
    red-blue)
        red_blue_loop "$@"
        ;;
    openwrt)
        openwrt
        ;;
    nuke)
        record_change_journal "nuke" "$@"
        require_debian_server "nuke"
        jeannie_log_start "nuke"
        jeannie_step_plan 1
        run_step "Nuke homelab cluster state" nuke
        echo "Log: ${JEANNIE_LOG_FILE}"
        ;;
    *)
        printf 'Unknown command: %s\n\n' "$1" >&2
        print_usage >&2
        exit 1
        ;;
esac
