#!/usr/bin/env bash
#
# Install the FCS Helper skill for the current user.
#
# Ubuntu tenant workspaces get the skill pushed by SSM. Mac government laptops
# have no SSM channel, so they install it with this script. The destination is
# the same on both: ~/.copilot/skills/fcs-helper.
#
# Re-running this always brings the skill up to date -- it replaces the installed
# copy rather than merging into it.
#
# It installs the skill and then REPORTS on three things without changing them:
# the GitHub CLI, a working python3, and whether the documentation bundle is
# reachable. None of those block the install.
#
# Usage:
#   curl -fsSL <url>/install-skill.sh | bash
#   ./install-skill.sh                      fetch from Artifactory
#   ./install-skill.sh --from FILE.tar.gz   install from a local archive
#   ./install-skill.sh --from DIR           install from a local directory
#   ./install-skill.sh --url URL            fetch from somewhere else
#   ./install-skill.sh --check-only         run the preflight checks, install nothing
#
# Written for bash 3.2, which is what macOS ships. No bash 4 features, no
# GNU-only flags, and it never reads stdin so it is safe to pipe into bash.

set -euo pipefail

# ---------------------------------------------------------------------------
# WHERE THE ARTEFACTS LIVE -- change this line to test against somewhere else.
#
# Each can also be overridden by an environment variable, so you can point the
# script at a different host without editing it:
#
#   FCS_ART_BASE=http://localhost:8000 ./install-skill.sh
#   FCS_SKILL_URL=file:///tmp/skilldist/skill-latest.tar.gz ./install-skill.sh
#
# curl understands file:// as well as http(s)://, so a path on disk works as a URL.
# --from is still the simplest way to install from a local copy.
# ---------------------------------------------------------------------------
ART_BASE="${FCS_ART_BASE:-https://artifactory.helix.gsa.gov/artifactory/sre-artifacts/fcs-helper}"
SKILL_URL="${FCS_SKILL_URL:-$ART_BASE/skill-latest.tar.gz}"
DOCS_URL="${FCS_DOCS_URL:-$ART_BASE/docs-bundle-latest.tar.gz}"

SKILLS_DIR="$HOME/.copilot/skills"
TARGET="$SKILLS_DIR/fcs-helper"
VERSION_FILE="$SKILLS_DIR/.fcs-helper-version"

SOURCE=""
CHECK_ONLY=0

ok()   { printf '  [OK]   %s\n' "$1"; }
warn() { printf '  [WARN] %s\n' "$1"; }
fail() { printf '  [FAIL] %s\n' "$1" >&2; }
step() { printf '\n%s\n' "$1"; }

usage() { sed -n '2,/^set -euo/p' "$0" | sed 's/^# \{0,1\}//'; }

while [ $# -gt 0 ]; do
    case "$1" in
        --from)       SOURCE="${2:-}"; shift 2 ;;
        --url)        SKILL_URL="${2:-}"; shift 2 ;;
        --check-only) CHECK_ONLY=1; shift ;;
        -h|--help)    usage; exit 0 ;;
        *) fail "unknown argument: $1"; printf 'Try --help\n' >&2; exit 2 ;;
    esac
done

printf 'FCS Helper -- skill installer\n'
printf 'Destination: %s\n' "$TARGET"

WORK=""
# This must always succeed. A trap whose last command fails replaces the script's
# exit status with that failure -- which made --check-only exit 1 while reporting
# that every check had passed.
cleanup() {
    if [ -n "$WORK" ]; then
        rm -rf "$WORK"
    fi
    return 0
}
trap cleanup EXIT

# ---------------------------------------------------------------- install
if [ "$CHECK_ONLY" -eq 0 ]; then
    step "Installing the skill"

    WORK=$(mktemp -d)
    STAGE="$WORK/stage"
    mkdir -p "$STAGE"

    if [ -n "$SOURCE" ] && [ -d "$SOURCE" ]; then
        # A directory: either the skill itself, or a parent containing fcs-helper.
        if [ -f "$SOURCE/SKILL.md" ]; then
            cp -R "$SOURCE" "$STAGE/fcs-helper"
        elif [ -f "$SOURCE/fcs-helper/SKILL.md" ]; then
            cp -R "$SOURCE/fcs-helper" "$STAGE/fcs-helper"
        else
            fail "$SOURCE contains no SKILL.md and no fcs-helper/SKILL.md"
            exit 1
        fi
        ok "copied from directory $SOURCE"

    elif [ -n "$SOURCE" ]; then
        if [ ! -f "$SOURCE" ]; then
            fail "no such file: $SOURCE"
            exit 1
        fi
        tar xzf "$SOURCE" -C "$STAGE" || { fail "could not extract $SOURCE"; exit 1; }
        ok "extracted $SOURCE"

    else
        printf '  fetching %s\n' "$SKILL_URL"
        if ! curl -fsSL --max-time 120 "$SKILL_URL" -o "$WORK/skill.tar.gz"; then
            fail "could not download the skill from Artifactory"
            printf '\n' >&2
            printf 'If you are off the network, install from a local copy instead:\n' >&2
            printf '  ./install-skill.sh --from /path/to/skill-latest.tar.gz\n' >&2
            printf '  ./install-skill.sh --from /path/to/repo/skills/fcs-helper\n' >&2
            exit 1
        fi
        tar xzf "$WORK/skill.tar.gz" -C "$STAGE" || { fail "downloaded archive would not extract"; exit 1; }
        ok "downloaded and extracted"
    fi

    if [ ! -f "$STAGE/fcs-helper/SKILL.md" ]; then
        fail "the source did not contain fcs-helper/SKILL.md -- refusing to install"
        exit 1
    fi

    # Replace rather than merge, so a re-run cannot leave stale files behind.
    # Install to a temporary name first, then swap, so a failure part-way through
    # does not destroy a working install.
    mkdir -p "$SKILLS_DIR"
    rm -rf "$TARGET.incoming"
    cp -R "$STAGE/fcs-helper" "$TARGET.incoming"

    HAD_PREVIOUS=0
    [ -d "$TARGET" ] && HAD_PREVIOUS=1

    rm -rf "$TARGET.previous"
    [ "$HAD_PREVIOUS" -eq 1 ] && mv "$TARGET" "$TARGET.previous"
    mv "$TARGET.incoming" "$TARGET"
    rm -rf "$TARGET.previous"

    if [ -f "$STAGE/VERSION" ]; then
        cp "$STAGE/VERSION" "$VERSION_FILE"
    else
        {
            printf 'skill: fcs-helper\n'
            printf 'commit: unknown (installed from %s)\n' "${SOURCE:-$SKILL_URL}"
            printf 'built: unknown\n'
            printf 'installed: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
        } > "$VERSION_FILE"
    fi

    COUNT=$(find "$TARGET" -type f | wc -l | tr -d ' ')
    if [ "$HAD_PREVIOUS" -eq 1 ]; then
        ok "updated the existing install ($COUNT files)"
    else
        ok "installed ($COUNT files)"
    fi

    COMMIT_LINE=$(grep '^commit:' "$VERSION_FILE" 2>/dev/null || true)
    [ -n "$COMMIT_LINE" ] && printf '  %s\n' "$COMMIT_LINE"
fi

# ---------------------------------------------------------------- preflight
step "Checking what the walkthrough needs (reporting only, nothing is changed)"

PROBLEMS=0

# 1. GitHub CLI.
if command -v gh >/dev/null 2>&1; then
    GH_VER=$(gh --version 2>/dev/null | head -1)
    ok "GitHub CLI present -- $GH_VER"
else
    warn "GitHub CLI (gh) not found. The walkthrough needs it."
    printf '         macOS:  brew install gh      (or download from https://cli.github.com)\n'
    printf '         Ubuntu: sudo apt install gh\n'
    PROBLEMS=$((PROBLEMS + 1))
fi

# 2. A python3 that actually runs. On macOS /usr/bin/python3 is a Command Line
#    Tools stub: it exists on PATH but can answer with an install prompt instead
#    of a version, so presence alone proves nothing.
if command -v python3 >/dev/null 2>&1; then
    if PY_VER=$(python3 -c 'import sys; print("%d.%d.%d" % sys.version_info[:3])' 2>/dev/null); then
        ok "python3 runs -- $PY_VER"
    else
        warn "python3 is on PATH but did not execute."
        printf '         On a Mac this usually means the Command Line Tools are missing.\n'
        printf '         Install them with:  xcode-select --install\n'
        PROBLEMS=$((PROBLEMS + 1))
    fi
else
    warn "python3 not found. The default walkthrough builds a Python app."
    printf '         macOS: xcode-select --install   (or install Python 3 directly)\n'
    PROBLEMS=$((PROBLEMS + 1))
fi

# 3. The documentation bundle. This is the skill's very first action and it needs
#    no credentials, so an unreachable bundle means a network or proxy problem
#    rather than anything to do with the install.
if command -v curl >/dev/null 2>&1; then
    CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 25 "$DOCS_URL" 2>/dev/null || printf 'none')
    if [ "$CODE" = "200" ]; then
        ok "documentation bundle reachable with no credentials"
    else
        warn "documentation bundle not reachable (HTTP ${CODE})."
        printf '         The skill fetches this first and it needs no login, so this is a\n'
        printf '         network, VPN or proxy question rather than an install problem.\n'
        printf '         URL: %s\n' "$DOCS_URL"
        PROBLEMS=$((PROBLEMS + 1))
    fi
else
    warn "curl not found, so the documentation bundle could not be checked"
    PROBLEMS=$((PROBLEMS + 1))
fi

# ---------------------------------------------------------------- summary
step "Summary"
if [ "$CHECK_ONLY" -eq 0 ]; then
    ok "skill installed at $TARGET"
    printf '  Open a Copilot chat and run /skills list to confirm it is picked up.\n'
    printf '  Then say: "I am new to FCS, help me deploy an app"\n'
fi

if [ "$PROBLEMS" -eq 0 ]; then
    ok "all checks passed"
else
    printf '  %s check(s) need attention above. The skill is installed either way --\n' "$PROBLEMS"
    printf '  it will walk you through the GitHub CLI itself, so a missing gh is not fatal.\n'
fi

exit 0
