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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
VERSION_FILE="$SKILL_DIR/VERSION"
COMPAT_FILE="$SKILL_DIR/compat.json"

read_json_string() {
  local key="$1"
  local file="$2"
  sed -n "s/.*\"$key\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" "$file" 2>/dev/null | head -1
}

normalize_version() {
  local version="${1#v}"
  version="${version%%[-+]*}"
  printf '%s' "$version"
}

semver_ge() {
  local current required
  current="$(normalize_version "$1")"
  required="$(normalize_version "$2")"

  local current_major current_minor current_patch
  local required_major required_minor required_patch
  IFS=. read -r current_major current_minor current_patch <<< "$current"
  IFS=. read -r required_major required_minor required_patch <<< "$required"

  current_major="${current_major:-0}"
  current_minor="${current_minor:-0}"
  current_patch="${current_patch:-0}"
  required_major="${required_major:-0}"
  required_minor="${required_minor:-0}"
  required_patch="${required_patch:-0}"

  if (( current_major != required_major )); then
    (( current_major > required_major ))
    return
  fi
  if (( current_minor != required_minor )); then
    (( current_minor > required_minor ))
    return
  fi
  (( current_patch >= required_patch ))
}

find_lj_awb() {
  if command -v lj-awb >/dev/null 2>&1; then
    command -v lj-awb
    return 0
  fi

  if command -v npm >/dev/null 2>&1; then
    local npm_prefix npm_bin
    npm_prefix="$(npm prefix -g 2>/dev/null || true)"
    npm_bin="$npm_prefix/bin/lj-awb"
    if [ -n "$npm_prefix" ] && [ -x "$npm_bin" ]; then
      printf '%s\n' "$npm_bin"
      return 0
    fi
  fi

  return 1
}

command_version() {
  local cmd="$1"
  "$cmd" --version 2>/dev/null | grep -Eo 'v?[0-9]+(\.[0-9]+){2}([-+][0-9A-Za-z.-]+)?' | head -1
}

SKILL_VERSION="$(cat "$VERSION_FILE" 2>/dev/null || printf '0.4.0')"
MIN_CLI_VERSION="$(read_json_string minCliVersion "$COMPAT_FILE")"
MIN_CLI_VERSION="${MIN_CLI_VERSION:-$SKILL_VERSION}"
CLI_VERSION="${LINGJING_AWB_CLI_VERSION:-$MIN_CLI_VERSION}"
CLI_PACKAGE="${LINGJING_AWB_CLI_PACKAGE:-@lingjingai/lj-awb-cli}"
CLI_PACKAGE_SPEC="${LINGJING_AWB_CLI_PACKAGE_SPEC:-$CLI_PACKAGE@$CLI_VERSION}"

if LJ_AWB_CMD="$(find_lj_awb)"; then
  INSTALLED_VERSION="$(command_version "$LJ_AWB_CMD" || true)"
  if [ -n "$INSTALLED_VERSION" ] && semver_ge "$INSTALLED_VERSION" "$MIN_CLI_VERSION"; then
    printf '%s\n' "$LJ_AWB_CMD"
    exit 0
  fi

  printf 'Found lj-awb %s, but this skill requires >= %s.\n' "${INSTALLED_VERSION:-unknown}" "$MIN_CLI_VERSION" >&2
fi

if [ "${LINGJING_AWB_AUTO_INSTALL:-1}" = "0" ]; then
  printf 'No compatible lj-awb CLI found. Install it first: npm install -g %s\n' "$CLI_PACKAGE_SPEC" >&2
  exit 1
fi

if ! command -v npm >/dev/null 2>&1; then
  printf 'No compatible lj-awb CLI found, and npm is unavailable. Install Node.js >=20 and npm, then run: npm install -g %s\n' "$CLI_PACKAGE_SPEC" >&2
  exit 1
fi

printf 'Installing lj-awb CLI: npm install -g %s\n' "$CLI_PACKAGE_SPEC" >&2
npm install -g "$CLI_PACKAGE_SPEC" >&2

if LJ_AWB_CMD="$(find_lj_awb)"; then
  INSTALLED_VERSION="$(command_version "$LJ_AWB_CMD" || true)"
  if [ -n "$INSTALLED_VERSION" ] && semver_ge "$INSTALLED_VERSION" "$MIN_CLI_VERSION"; then
    printf '%s\n' "$LJ_AWB_CMD"
    exit 0
  fi
fi

printf 'Installed %s, but lj-awb is still not available on PATH. Check npm global bin path, then retry.\n' "$CLI_PACKAGE_SPEC" >&2
exit 1
