#!/bin/bash
#
# Build the distributable agent zip file.
# Run this whenever you make changes to the agent code.
#
# Usage: ./scripts/build-zip.sh
# Output: site/agent.zip (+ site/version.json)

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(dirname "$SCRIPT_DIR")"
cd "$ROOT"

echo "[build-zip] Packaging agent for distribution..."

# Ensure site directory exists
mkdir -p site

# Create a temporary staging directory
# Use a subdirectory of the project root to avoid Windows path issues
# (mktemp -d creates /tmp/ paths that Node.js resolves differently)
STAGE="$ROOT/.build-stage-$$"
rm -rf "$STAGE"
mkdir -p "$STAGE"
trap "rm -rf '$STAGE'" EXIT

# ── Core files ────────────────────────────────────────────────

CORE_FILES=(
  agent.mjs
  config.mjs
  db.mjs
  server.mjs
  skills.mjs
  memory.mjs
  workspace.mjs
  workspace-manager.mjs
  task-scheduler.mjs
  llm.mjs
  json-utils.mjs
  evolution.mjs
  voice-activation.mjs
  knowledge-graph.mjs
  entity-extraction.mjs
  semantic-search.mjs
  ingestion.mjs
  fetch-utils.mjs
  file-watcher.mjs
  persona.mjs
  vector-cache.mjs
  session-store.mjs
  chat-session.mjs
  background-queue.mjs
  askuser-bridge.mjs
  claude.mjs
  logger.mjs
  meta-reflection.mjs
  refined-instructions.mjs
  scheduler.mjs
  personality.md
  tools.md
  package.json
  version.json
  setup.sh
  setup.bat
  update.sh
  update.bat
  reset.sh
  reset.bat
  watchdog.sh
  install.sh
)

for f in "${CORE_FILES[@]}"; do
  if [ -f "$f" ]; then
    cp "$f" "$STAGE/$f"
  fi
done

# ── Directories ───────────────────────────────────────────────

for dir in adapters agentic-tools skills scripts public cognitive multimodal electron; do
  if [ -d "$dir" ]; then
    mkdir -p "$STAGE/$dir"
    cp -R "$dir"/* "$STAGE/$dir/" 2>/dev/null || true
  fi
done

# ── Claude tool policies ──────────────────────────────────────
# Project-level settings that protect agent files when Claude is
# used as the LLM backend (deny destructive operations).

if [ -f ".claude/settings.json" ]; then
  mkdir -p "$STAGE/.claude"
  cp ".claude/settings.json" "$STAGE/.claude/settings.json"
  echo "[build-zip] Included .claude/settings.json (tool policies)"
fi

# ── Create empty directories that the agent expects ───────────

mkdir -p "$STAGE/workspaces/default"
mkdir -p "$STAGE/data/wake-words"
mkdir -p "$STAGE/data/wake-word-models"
touch "$STAGE/data/wake-words/.gitkeep"

# Copy wake word ONNX models if available
if [ -d "data/wake-word-models" ]; then
  cp data/wake-word-models/*.onnx "$STAGE/data/wake-word-models/" 2>/dev/null || true
  MODEL_COUNT=$(ls "$STAGE/data/wake-word-models/"*.onnx 2>/dev/null | wc -l | tr -d ' ')
  echo "[build-zip] Included $MODEL_COUNT wake word model files"
fi

# ── Create a starter journal ──────────────────────────────────

echo "# Journal" > "$STAGE/journal.md"

# ── Clean the package.json for distribution ───────────────────
# (Remove agent-specific name, keep it generic)

# Convert paths for Node.js on Windows (Git Bash /c/... -> C:/...)
if command -v cygpath &>/dev/null; then
  STAGE_NODE=$(cygpath -w "$STAGE")
  ROOT_NODE=$(cygpath -w "$ROOT")
else
  STAGE_NODE="$STAGE"
  ROOT_NODE="$ROOT"
fi
node -e "
  const fs = require('fs');
  const path = require('path');
  const stageDir = path.resolve('${STAGE_NODE//\\/\\\\}');
  const rootDir = path.resolve('${ROOT_NODE//\\/\\\\}');
  const pkg = JSON.parse(fs.readFileSync(path.join(stageDir, 'package.json'), 'utf-8'));
  pkg.name = 'autonomous-agent';
  const ver = JSON.parse(fs.readFileSync(path.join(rootDir, 'version.json'), 'utf-8'));
  pkg.version = ver.version || '4.2.1';
  pkg.description = 'Autonomous AI agent with web interface, persistent memory, and self-improving skills';
  fs.writeFileSync(path.join(stageDir, 'package.json'), JSON.stringify(pkg, null, 2) + '\n');
"

# ── Remove dev-only files from skills ─────────────────────────
# (meta-develop requires special sandbox setup — keep it but note it)

# ── Fix line endings for shell scripts ─────────────────────────
# Windows environments may produce CRLF line endings. Strip \r
# from all .sh files so they work on macOS/Linux without
# "bad interpreter" or syntax errors.

for shfile in "$STAGE"/*.sh "$STAGE"/scripts/*.sh; do
  [ -f "$shfile" ] || continue
  tr -d '\r' < "$shfile" > "$shfile.tmp" && mv "$shfile.tmp" "$shfile"
  chmod +x "$shfile"
done
echo "[build-zip] Ensured Unix line endings on all .sh files"

# ── Create the zip ────────────────────────────────────────────

# Read version for the zip filename
ZIP_VERSION=$(node -e "const p=require('path');console.log(JSON.parse(require('fs').readFileSync(p.join(p.resolve('${ROOT_NODE//\\/\\\\}'),'version.json'),'utf-8')).version||'4.2.1')" 2>/dev/null || echo "4.2.1")
ZIP_NAME="ai-do-agent-v${ZIP_VERSION}.zip"

cd "$STAGE"
if command -v zip &>/dev/null; then
  zip -rq "$ROOT/site/$ZIP_NAME" . -x "*.DS_Store" "*.db" "*.db-*"
else
  # Windows fallback: use PowerShell Compress-Archive
  STAGE_WIN=$(cygpath -w "$STAGE" 2>/dev/null || echo "$STAGE")
  ZIP_WIN=$(cygpath -w "$ROOT/site/$ZIP_NAME" 2>/dev/null || echo "$ROOT/site/$ZIP_NAME")
  powershell.exe -NoProfile -Command "Compress-Archive -Path '${STAGE_WIN}\\*' -DestinationPath '${ZIP_WIN}' -Force"
fi
cd "$ROOT"

# Also create agent.zip as a stable link (for update.sh compatibility)
cp "site/$ZIP_NAME" "site/agent.zip"

# Copy version.json to site for update checking
cp version.json site/version.json

# Get zip size
ZIP_SIZE=$(ls -lh "site/$ZIP_NAME" | awk '{print $5}')
echo "[build-zip] Created site/$ZIP_NAME ($ZIP_SIZE)"
echo "[build-zip] Also copied as site/agent.zip (for auto-updater)"
echo "[build-zip] Copied version.json to site/"
echo "[build-zip] Done!"
