#!/usr/bin/env bash
set -euo pipefail

DEFAULT_BASE_URL="https://autonep.hk.kokocloud.top"
DEFAULT_VERSION="20260520_032429_04ce125"

usage() {
  cat <<'USAGE'
Install or update an SSB worker release.

Usage:
  bash install_ssbworker.sh [options]

Options:
  --prefix DIR       Install directory. Default: ~/ssbworker-autonep
  --base-url URL     Release base URL. Default is baked into this script.
  --version VERSION  Install a specific version from releases/.
  --update           Update an existing install in place, preserving config/token/logs/venv.
  --skip-deps        Do not run scripts/install_python_deps.sh after install.
  --force            Replace prefix when it exists and --update is not set.
  -h, --help         Show this help.
USAGE
}

expand_path() {
  local value="$1"
  value="${value/#\~/$HOME}"
  printf '%s\n' "$value"
}

fetch() {
  local url="$1"
  local output="$2"
  curl -fsSL "$url" -o "$output"
}

json_value() {
  local file="$1"
  local key="$2"
  python3 - "$file" "$key" <<'PY'
import json
import sys
with open(sys.argv[1], "r", encoding="utf-8") as f:
    data = json.load(f)
value = data.get(sys.argv[2], "")
print(value)
PY
}

sha256_file() {
  sha256sum "$1" | awk '{print $1}'
}

prefix="$HOME/ssbworker-autonep"
base_url="$DEFAULT_BASE_URL"
version=""
update=0
skip_deps=0
force=0

while [ "$#" -gt 0 ]; do
  case "$1" in
    --prefix)
      prefix="$(expand_path "$2")"
      shift 2
      ;;
    --base-url)
      base_url="${2%/}"
      shift 2
      ;;
    --version)
      version="$2"
      shift 2
      ;;
    --update)
      update=1
      shift
      ;;
    --skip-deps)
      skip_deps=1
      shift
      ;;
    --force)
      force=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 2
      ;;
  esac
done

if ! command -v python3 >/dev/null 2>&1; then
  echo "python3 is required" >&2
  exit 1
fi
if ! command -v curl >/dev/null 2>&1; then
  echo "curl is required" >&2
  exit 1
fi
if ! command -v sha256sum >/dev/null 2>&1; then
  echo "sha256sum is required" >&2
  exit 1
fi

tmp_dir="$(mktemp -d "${TMPDIR:-/tmp}/ssbworker-install.XXXXXX")"
trap 'rm -rf "$tmp_dir"' EXIT

latest_json="$tmp_dir/latest.json"
fetch "$base_url/latest.json" "$latest_json"

latest_version="$(json_value "$latest_json" version)"
artifact="$(json_value "$latest_json" artifact)"
artifact_url="$(json_value "$latest_json" artifact_url)"
expected_sha="$(json_value "$latest_json" sha256)"

if [ -n "$version" ] && [ "$version" != "$latest_version" ]; then
  artifact="ssbworker-${version}.tar.gz"
  artifact_url="$base_url/releases/$artifact"
  expected_sha=""
else
  version="$latest_version"
fi

archive="$tmp_dir/$artifact"
echo "Downloading SSB worker $version from $artifact_url"
fetch "$artifact_url" "$archive"

if [ -n "$expected_sha" ]; then
  actual_sha="$(sha256_file "$archive")"
  if [ "$actual_sha" != "$expected_sha" ]; then
    echo "SHA256 mismatch for $artifact" >&2
    echo "expected: $expected_sha" >&2
    echo "actual  : $actual_sha" >&2
    exit 1
  fi
fi

extract_dir="$tmp_dir/extract"
mkdir -p "$extract_dir"
tar -C "$extract_dir" -xzf "$archive"
release_root="$extract_dir/ssbworker"
if [ ! -d "$release_root" ]; then
  echo "Release archive does not contain ssbworker/ root" >&2
  exit 1
fi

prefix="$(mkdir -p "$(dirname "$prefix")" && cd "$(dirname "$prefix")" && pwd)/$(basename "$prefix")"

if [ -e "$prefix" ] && [ "$update" -ne 1 ]; then
  if [ "$force" -ne 1 ]; then
    echo "Install prefix already exists: $prefix" >&2
    echo "Use --update to preserve local state or --force to replace it." >&2
    exit 1
  fi
  rm -rf "$prefix"
fi

if [ "$update" -eq 1 ] && [ -e "$prefix" ]; then
  backup_dir="$tmp_dir/preserve"
  mkdir -p "$backup_dir"
  for path in config/config.yaml .worker_token logs run venv; do
    if [ -e "$prefix/$path" ]; then
      mkdir -p "$backup_dir/$(dirname "$path")"
      mv "$prefix/$path" "$backup_dir/$path"
    fi
  done
  rm -rf "$prefix"
  mkdir -p "$prefix"
  cp -a "$release_root/." "$prefix/"
  for path in config/config.yaml .worker_token logs run venv; do
    if [ -e "$backup_dir/$path" ]; then
      mkdir -p "$prefix/$(dirname "$path")"
      rm -rf "$prefix/$path"
      mv "$backup_dir/$path" "$prefix/$path"
    fi
  done
else
  mkdir -p "$(dirname "$prefix")"
  rm -rf "$prefix"
  cp -a "$release_root" "$prefix"
fi

mkdir -p "$prefix/config" "$prefix/logs" "$prefix/run"
if [ ! -f "$prefix/config/config.yaml" ] && [ -f "$prefix/config/config.yaml.example" ]; then
  cp "$prefix/config/config.yaml.example" "$prefix/config/config.yaml"
  echo "Created config/config.yaml from example; review it before starting the worker."
fi

chmod +x "$prefix"/scripts/*.sh 2>/dev/null || true
printf '%s\n' "$version" > "$prefix/.ssbworker-version"

if [ "$skip_deps" -ne 1 ]; then
  "$prefix/scripts/install_python_deps.sh"
fi

echo "Installed SSB worker $version to: $prefix"
echo
echo "Next commands:"
echo "  cd $prefix"
echo "  ./scripts/check_runtime.sh"
echo "  ./scripts/start_worker.sh"
echo "  ./scripts/status.sh"
