#!/usr/bin/env bash
# cocottetech V4 platform — Task Runner (root)
# Usage: ./run <command> [args...]
#
# Integrates:
#   - lilith-style manifest management (./run manifest validate ...)
#   - platform pnpm/turbo verbs (delegated to @platform/)
#   - Cloud DX: forge:* (self-hosted Forgejo on DO) and dist:* (ephemeral test fleet)
#
# Source of truth for ports/manifest still @platform/infrastructure/ports.yaml + manage-apps.
# See CLAUDE.md, INFRA.md § (new cloud section), docs/CLOUD_DX_HANDOFF.md

set -uo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Source all run modules (forge, dist, any future)
for _script in "$REPO_ROOT/scripts/run/"*.sh; do
    # shellcheck disable=SC1090
    source "$_script"
done
unset _script

# Colors (best-effort)
RED=$'\e[31m' YELLOW=$'\e[33m' BLUE=$'\e[34m' NC=$'\e[0m' || true

usage() {
    echo -e "${BLUE}cocottetech${NC} — Task Runner"
    echo ""
    echo "Usage: ./run <command> [args...]"
    echo ""
    echo -e "${YELLOW}Platform (pnpm/turbo in @platform/)${NC}"
    echo "  build                    pnpm build (turbo)"
    echo "  typecheck                pnpm typecheck (turbo)"
    echo "  test                     pnpm test (turbo)"
    echo "  test:unit                pnpm test:unit"
    echo "  lint                     pnpm lint"
    echo "  clean                    pnpm clean"
    echo ""
    echo -e "${YELLOW}Manifest & ports (see CLAUDE.md — tool-managed)${NC}"
    echo "  manifest [subcmd]        manage-apps wrapper + ports sync (validate recommended after edits)"
    echo "  manifest:validate        shorthand for manifest validate"
    echo ""
    echo -e "${YELLOW}Cloud DX (DigitalOcean + self-hosted Forgejo — see docs/CLOUD_DX_HANDOFF.md)${NC}"
    echo "  (SSH fleet key generated: ~/.ssh/id_cocotte_fleet — register its .pub in DO as 'cocotte-fleet')"
    echo "  forge                    Show forge:* help (auto key ID lookup)"
    echo "  forge:up                 Bring up (or restore from snapshot) the cocotte-forge droplet; refreshes ~/.vault/cocotte_forge_creds"
    echo "  forge:down               Snapshot + destroy (idle ~$0.30/mo)"
    echo "  forge:dns [name]         Add/update /etc/hosts entry (default: cocotteforge)"
    echo "  dist                     Show dist:* help"
    echo "  dist:check               Offline terraform fmt/validate/test (mocked, zero cost)"
    echo "  dist:up <N> [size] [region]   Spin N workers from golden image"
    echo "  dist:down                Tear fleet down (workers=0)"
    echo "  dist:test                Offload pnpm test to a worker"
    echo "  dist:typecheck           Offload typecheck to a worker"
    echo "  dist:build               Offload build to a worker"
    echo "  dist:sync [ref]          Fast-forward workers to ref + pnpm install"
    echo "  (one-shot human bring-up script: scripts/cloud-bringup.sh )"
    echo ""
    echo "All other commands fall through to cmd_* defined in scripts/run/*.sh"
}

# Platform delegations
cmd_build()      { (cd "$REPO_ROOT/@platform" && pnpm build "$@"); }
cmd_typecheck()  { (cd "$REPO_ROOT/@platform" && pnpm typecheck "$@"); }
cmd_test()       { (cd "$REPO_ROOT/@platform" && pnpm test "$@"); }
cmd_test_unit()  { (cd "$REPO_ROOT/@platform" && pnpm test:unit "$@"); }
cmd_lint()       { (cd "$REPO_ROOT/@platform" && pnpm lint "$@"); }
cmd_clean()      { (cd "$REPO_ROOT/@platform" && pnpm clean "$@"); }

# Manifest (lilith-style)
cmd_manifest() {
    shift || true
    if command -v manage-apps >/dev/null 2>&1; then
        manage-apps "$@"
    else
        echo -e "${YELLOW}manage-apps not found in PATH${NC} (expected ~/.bun/bin or @tools). Falling back to @platform script if present." >&2
        if [ -f "$REPO_ROOT/@platform/scripts/sync-ports.sh" ]; then
            echo "Hint: ports are synced via @platform/scripts/sync-ports.sh (run manually or extend this verb)."
        fi
        # Always allow validate to be a no-op success for now if tool missing
        if [ "${1:-}" = "validate" ]; then
            echo "manifest validate (tool missing — treated as ok for bootstrap)"
            return 0
        fi
        return 1
    fi
}
cmd_manifest_validate() { cmd_manifest manifest validate "$@"; }

# Special dispatch
COMMAND="${1:-}"
shift 2>/dev/null || true

case "$COMMAND" in
    help|--help|-h|"") usage; exit 0 ;;
    manifest)          cmd_manifest manifest "$@"; exit $? ;;
    manifest:validate) cmd_manifest_validate "$@"; exit $? ;;
    build|typecheck|test|test:unit|lint|clean)
        # Reconstruct for the cmd_ form
        exec "$0" "$COMMAND" "$@"
        ;;
esac

# Data-driven: verb or verb:target → cmd_verb or cmd_verb_target
FUNC="cmd_${COMMAND//[:-]/_}"
if declare -F "$FUNC" >/dev/null 2>&1; then
    "$FUNC" "$@"
    exit $?
fi

echo -e "${RED}Unknown command: $COMMAND${NC}"
echo ""
usage
exit 1
