#!/usr/bin/env bash
# Purpose: verify an agentic coding workstation end to end - the three role aliases answer,
#          each configured agent is installed, the MCP list is declared, the sandbox image
#          exists and its boundary test passes - and record the result in the lab notebook.
# Platform: all (spark, strix, nvidia natively; mac with Docker Desktop, or with the
#           sandbox checks skipped on the dedicated-user route)
# Minimum memory: 16 GB for the agent role behind the gateway alias
# Assumes: the workstation created by setup-workstation.sh, the Part 9 gateway running,
#          curl and python3 on PATH, and GATEWAY_KEY exported. It only reads and makes one
#          small completion request per role alias.
#
# Usage:
#   ./check-workstation.sh
#   WORKSTATION=~/agentic SKIP_SANDBOX=1 ./check-workstation.sh

set -uo pipefail

WORKSTATION="${WORKSTATION:-$HOME/agentic-workstation}"
GATEWAY_URL="${GATEWAY_URL:-http://127.0.0.1:4000}"
AGENT_ALIAS="${AGENT_ALIAS:-local/agent}"
COMPLETION_ALIAS="${COMPLETION_ALIAS:-local/completion}"
JUDGE_ALIAS="${JUDGE_ALIAS:-local/judge}"
SKIP_SANDBOX="${SKIP_SANDBOX:-0}"
LABBOOK="${LABBOOK:-$WORKSTATION/evidence/labbook.md}"

passes=0
failures=0
results=""

record() {
    local name="$1" verdict="$2" detail="$3"
    if [ "$verdict" = "pass" ]; then
        passes=$(( passes + 1 ))
        printf '  PASS  %-30s %s\n' "$name" "$detail"
    else
        failures=$(( failures + 1 ))
        printf '  FAIL  %-30s %s\n' "$name" "$detail"
    fi
    results="${results}${results:+,}\"${name}\":\"${verdict}\""
}

echo "Workstation check: $WORKSTATION"
echo

# ------------------------------------------------------------------------ 1. the layout
echo "Layout"
for directory in agents sandbox mcp projects evidence; do
    if [ -d "$WORKSTATION/$directory" ]; then
        record "layout-$directory" "pass" "present"
    else
        record "layout-$directory" "fail" "missing; run setup-workstation.sh"
    fi
done
echo

# ------------------------------------------------------------------- 2. the role aliases
echo "Roles"
check_alias() {
    # check_alias <name> <alias>
    local name="$1" alias="$2" body status
    body="$(printf '{"model":"%s","messages":[{"role":"user","content":"ok"}],"max_tokens":8}' "$alias")"
    status="$(curl --silent --output /dev/null --write-out '%{http_code}' --max-time 120 \
        --request POST "$GATEWAY_URL/v1/chat/completions" \
        --header "Authorization: Bearer ${GATEWAY_KEY:-}" \
        --header 'Content-Type: application/json' \
        --data "$body" || echo 000)"
    case "$status" in
        2*) record "$name" "pass" "answered with HTTP $status" ;;
        000) record "$name" "fail" "no response; is the gateway running?" ;;
        *) record "$name" "fail" "HTTP $status" ;;
    esac
}
check_alias "role-agent" "$AGENT_ALIAS"
check_alias "role-completion" "$COMPLETION_ALIAS"
check_alias "role-judge" "$JUDGE_ALIAS"

if [ "$AGENT_ALIAS" = "$JUDGE_ALIAS" ]; then
    record "judge-is-a-different-model" "fail" "the judge and the agent are the same alias"
else
    record "judge-is-a-different-model" "pass" "agent and judge are different aliases"
fi
echo

# ------------------------------------------------------------------------- 3. the agents
echo "Agents"
configured=0
for pair in "aider:agents/aider-model-settings.yml" \
            "opencode:agents/opencode.json" \
            "codex:agents/codex-config.toml" \
            "goose:agents/goose-local-env.txt"; do
    tool="${pair%%:*}"
    file="${pair#*:}"
    if command -v "$tool" >/dev/null 2>&1 && [ -f "$WORKSTATION/$file" ]; then
        record "agent-$tool" "pass" "installed and configured"
        configured=$(( configured + 1 ))
    elif [ -f "$WORKSTATION/$file" ]; then
        record "agent-$tool" "fail" "configuration present but $tool is not on PATH"
    else
        printf '  ----  %-30s %s\n' "agent-$tool" "not configured on this workstation"
    fi
done

if [ "$configured" -ge 2 ]; then
    record "at-least-two-agents" "pass" "$configured agents installed and configured"
else
    record "at-least-two-agents" "fail" "only $configured; the project asks for two"
fi
echo

# --------------------------------------------------------------------- 4. the MCP servers
echo "MCP"
if [ -f "$WORKSTATION/mcp/mcp-servers.json" ]; then
    count="$(WORKSTATION="$WORKSTATION" python3 - <<'PY'
import json
import os

path = os.path.join(os.environ["WORKSTATION"], "mcp", "mcp-servers.json")
try:
    with open(path, "r", encoding="utf-8") as handle:
        data = json.load(handle)
except (OSError, json.JSONDecodeError):
    print(-1)
else:
    print(len(data.get("mcpServers") or {}))
PY
)"
    if [ "$count" = "-1" ]; then
        record "mcp-list-valid" "fail" "mcp/mcp-servers.json is not valid JSON"
    elif [ "$count" = "0" ]; then
        record "mcp-list-valid" "fail" "no servers declared; wire in at least one from Part 24"
    else
        record "mcp-list-valid" "pass" "$count server(s) declared"
    fi
else
    record "mcp-list-valid" "fail" "mcp/mcp-servers.json is missing"
fi
echo

# ------------------------------------------------------------------------- 5. the sandbox
echo "Sandbox"
if [ "$SKIP_SANDBOX" = "1" ]; then
    printf '  ----  %-30s %s\n' "sandbox" "skipped by request; record why in the runbook"
else
    if [ -f "$WORKSTATION/sandbox/compose-sandbox.yaml" ]; then
        record "sandbox-compose-present" "pass" "compose-sandbox.yaml present"
    else
        record "sandbox-compose-present" "fail" "compose-sandbox.yaml missing"
    fi

    if [ -f "$WORKSTATION/sandbox/.env" ]; then
        if grep -q -E '^(PROJECT_DIR|GATEWAY_URL|AGENT_GATEWAY_KEY)=$' "$WORKSTATION/sandbox/.env"; then
            record "sandbox-env-complete" "fail" "sandbox/.env still has empty required values"
        else
            record "sandbox-env-complete" "pass" "sandbox/.env has no empty required values"
        fi
    else
        record "sandbox-env-complete" "fail" "sandbox/.env is missing"
    fi

    if command -v docker >/dev/null 2>&1 \
        && docker image inspect agent-sandbox:workstation >/dev/null 2>&1; then
        record "sandbox-image-built" "pass" "agent-sandbox:workstation exists"
    else
        record "sandbox-image-built" "fail" "image not built; run setup-workstation.sh"
    fi

    latest_sheet="$(grep -l 'part-25-sandbox-your-agent' "$WORKSTATION/evidence"/*.md 2>/dev/null | head -1 || true)"
    if [ -n "$latest_sheet" ]; then
        record "boundary-test-recorded" "pass" "evidence found in $(basename "$latest_sheet")"
    else
        record "boundary-test-recorded" "fail" "no boundary-test record in evidence/"
    fi
fi
echo

# -------------------------------------------------------------------------- 6. the runbook
echo "Runbook"
if [ -f "$WORKSTATION/workstation-runbook.md" ]; then
    if grep -q -E '^\|[[:space:]]*(Agent|Completion|Judge)[[:space:]]*\|[^|]*\|[[:space:]]*\|' \
        "$WORKSTATION/workstation-runbook.md"; then
        record "runbook-filled-in" "fail" "the runbook still has empty rows in the roles table"
    else
        record "runbook-filled-in" "pass" "the roles table has been filled in"
    fi
else
    record "runbook-filled-in" "fail" "workstation-runbook.md is missing"
fi

echo
echo "$passes passed, $failures failed."

mkdir -p "$(dirname "$LABBOOK")" 2>/dev/null || true
RESULTS="$results" PASSES="$passes" FAILURES="$failures" LABBOOK="$LABBOOK" \
WORKSTATION="$WORKSTATION" python3 - <<'PY'
import datetime
import json
import os

record = {
    "lab": "part-25-agentic-workstation",
    "recorded": datetime.datetime.now(datetime.timezone.utc)
    .replace(microsecond=0)
    .isoformat(),
    "workstation": os.environ["WORKSTATION"],
    "checks": json.loads("{" + os.environ["RESULTS"] + "}"),
    "passed": int(os.environ["PASSES"]),
    "failed": int(os.environ["FAILURES"]),
    "complete": os.environ["FAILURES"] == "0",
}
try:
    with open(os.environ["LABBOOK"], "a", encoding="utf-8") as handle:
        handle.write(json.dumps(record) + "\n")
    print("recorded in " + os.environ["LABBOOK"])
except OSError as error:
    print("could not write the lab notebook: " + str(error))
PY

if [ "$failures" -ne 0 ]; then
    exit 1
fi
