#!/usr/bin/env bash
# Runs objectiveai-cli tests.
# Output is captured to .logs/test/objectiveai-cli.txt.
#
# Usage:
#   bash objectiveai-cli/test.sh
#   bash objectiveai-cli/test.sh -- --test-threads=1   # pass args to cargo test

set -euo pipefail

MODULE="objectiveai-cli"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
LOG_DIR="$REPO_ROOT/.logs/test"
LOG_FILE="$LOG_DIR/$MODULE.txt"

mkdir -p "$LOG_DIR"

# Diagnostic cross-layer log: PROXY/API/CLI components all append
# event lines to this file when the env var is set. Truncated at the
# start of every run. Children (api server, cli binary subprocess)
# inherit this env so all three layers write to the same file.
export OBJECTIVEAI_DIAGNOSTIC_LOG="$LOG_DIR/diagnostic.log"
: > "$OBJECTIVEAI_DIAGNOSTIC_LOG"

# Deterministically wipe CLI test artifacts on every exit path (success,
# failure, or interrupt). Keeps the tests folder free of gitignored runtime
# state (logs, cached repos, filesystem config) between runs.
#
# Also reap the api server we spawned, if any. CLI_TEST_API_PID is set
# below only when this script spawned the server itself — under the
# root test.sh harness OBJECTIVEAI_TEST_PORT is pre-set and we leave
# the parent's server alone.
CLI_TESTS_SCRATCH="$SCRIPT_DIR/tests/.objectiveai"
cleanup() {
  rm -rf "$CLI_TESTS_SCRATCH"
  if [ -n "${CLI_TEST_API_PID:-}" ]; then
    kill "$CLI_TEST_API_PID" 2>/dev/null || true
    wait "$CLI_TEST_API_PID" 2>/dev/null || true
  fi
  if [ -n "${CLI_TEST_MCP_PID:-}" ]; then
    kill "$CLI_TEST_MCP_PID" 2>/dev/null || true
    wait "$CLI_TEST_MCP_PID" 2>/dev/null || true
  fi
}
trap cleanup EXIT INT TERM
cleanup  # start from a clean slate as well

# Parse flags
CARGO_ARGS=()
while [[ $# -gt 0 ]]; do
  case "$1" in
    --) shift; CARGO_ARGS=("$@"); break ;;
    *)  CARGO_ARGS+=("$1"); shift ;;
  esac
done

# Spawn the test api server only if not already provided by a parent
# harness (e.g. the root test.sh). Same pattern as objectiveai-sdk-{py,js,go}.
if [ -z "${OBJECTIVEAI_TEST_PORT:-}" ]; then
  read -r PORT CLI_TEST_API_PID < <(bash "$REPO_ROOT/test-spawn-api-server.sh" 2>>"$LOG_FILE")
  export OBJECTIVEAI_TEST_PORT="$PORT"
fi

# Spawn the test MCP filesystem server only if not already provided.
# Required for the snapshot tests that exercise `client_objectiveai_mcp`
# reverse-attach: the CLI's `ConduitMcpHandler` dials this URL on every
# inbound `server_request` from the API's MCP proxy.
if [ -z "${OBJECTIVEAI_MCP_ADDRESS:-}" ]; then
  read -r MCP_URL CLI_TEST_MCP_PID < <(bash "$REPO_ROOT/test-spawn-mcp-server.sh" 2>>"$LOG_FILE")
  export OBJECTIVEAI_MCP_ADDRESS="$MCP_URL"
fi

# Run tests, capture all output
if cargo test --manifest-path "$SCRIPT_DIR/Cargo.toml" "${CARGO_ARGS[@]}" > "$LOG_FILE" 2>&1; then
  PASSED=$(sed -n 's/.* \([0-9][0-9]*\) passed.*/\1/p' "$LOG_FILE" | awk '{s+=$1} END {print s+0}')
  FAILED=$(sed -n 's/.* \([0-9][0-9]*\) failed.*/\1/p' "$LOG_FILE" | awk '{s+=$1} END {print s+0}')
  TOTAL=$((PASSED + FAILED))
  echo "$MODULE: PASS $PASSED/$TOTAL"
else
  PASSED=$(sed -n 's/.* \([0-9][0-9]*\) passed.*/\1/p' "$LOG_FILE" | awk '{s+=$1} END {print s+0}')
  FAILED=$(sed -n 's/.* \([0-9][0-9]*\) failed.*/\1/p' "$LOG_FILE" | awk '{s+=$1} END {print s+0}')
  TOTAL=$((PASSED + FAILED))
  if [ "$TOTAL" -gt 0 ]; then
    echo "$MODULE: FAIL $PASSED/$TOTAL"
  else
    echo "$MODULE: FAIL"
  fi
  exit 1
fi
