#!/usr/bin/env bash
# Trinh cai AIHOT.vn Skill (aihot-vn).
#
#   bash <(curl -fsSL https://aihot.vn/aihot-skill/install.sh) --target agents
#   bash <(curl -fsSL https://aihot.vn/aihot-skill/install.sh) --target claude
#   bash <(curl -fsSL https://aihot.vn/aihot-skill/install.sh) --dir "$HOME/duong/dan/aihot-vn"
#
# Cach lam: tai manifest.sha256 va tung tep trong do vao thu muc tam CUNG o dia voi dich,
# kiem SHA-256 tung tep va ten Skill, chi khi tat ca dung moi thay thu muc dich (doi ten).
# Khong ghi de thu muc khong phai cua aihot-vn, khong dung sudo, khong sua file ngoai thu
# muc dich (va lien ket ~/.claude/skills/aihot-vn khi --target claude).
set -euo pipefail

BASE_URL="${AIHOT_SKILL_BASE:-https://aihot.vn/aihot-skill}"
SKILL_NAME="aihot-vn"
TARGET=""
DEST=""
LINK=""

usage() {
  cat <<'EOF'
Cài AIHOT.vn Skill (aihot-vn).

Cách dùng:
  install.sh --target agents   Cài vào ~/.agents/skills/aihot-vn (Codex, Gemini CLI, Copilot, OpenCode)
  install.sh --target claude   Như trên, thêm liên kết ~/.claude/skills/aihot-vn cho Claude Code
  install.sh --dir <thư mục>   Cài vào đúng thư mục chỉ định
  install.sh --help            Hiện hướng dẫn này

Không có tham số thì trình cài chỉ hiện hướng dẫn và thoát, không đoán nền tảng.
EOF
}

die() {
  echo "Lỗi: $*" >&2
  exit 1
}

while [ $# -gt 0 ]; do
  case "$1" in
    --target) [ $# -ge 2 ] || die "thiếu giá trị cho --target"; TARGET="$2"; shift 2 ;;
    --target=*) TARGET="${1#*=}"; shift ;;
    --dir) [ $# -ge 2 ] || die "thiếu giá trị cho --dir"; DEST="$2"; shift 2 ;;
    --dir=*) DEST="${1#*=}"; shift ;;
    -h|--help) usage; exit 0 ;;
    *) usage >&2; die "tham số không hợp lệ: $1" ;;
  esac
done

if [ -z "$TARGET" ] && [ -z "$DEST" ]; then
  usage
  exit 0
fi
[ -n "${HOME:-}" ] || die "biến HOME chưa được đặt"

if [ -n "$TARGET" ]; then
  [ -z "$DEST" ] || die "chỉ dùng một trong hai: --target hoặc --dir"
  case "$TARGET" in
    agents|codex|gemini|copilot|opencode) DEST="$HOME/.agents/skills/$SKILL_NAME" ;;
    claude) DEST="$HOME/.agents/skills/$SKILL_NAME"; LINK="$HOME/.claude/skills/$SKILL_NAME" ;;
    *) die "--target phải là agents hoặc claude (hoặc codex, gemini, copilot, opencode)" ;;
  esac
fi

case "$DEST" in
  /*) ;;
  *) DEST="$(pwd)/$DEST" ;;
esac
DEST="${DEST%/}"
case "$DEST" in
  ''|/|"$HOME") die "thư mục đích không hợp lệ: '$DEST'" ;;
esac

command -v curl >/dev/null 2>&1 || die "cần cài curl"
if command -v sha256sum >/dev/null 2>&1; then
  sha256_of() { sha256sum "$1" | awk '{print $1}'; }
elif command -v shasum >/dev/null 2>&1; then
  sha256_of() { shasum -a 256 "$1" | awk '{print $1}'; }
else
  die "cần sha256sum hoặc shasum để kiểm tra gói"
fi

CURL_OPTS=(-fsSL --retry 2 --max-time 60)
case "$BASE_URL" in
  https://*) CURL_OPTS+=(--proto '=https' --tlsv1.2) ;;
  *) echo "Cảnh báo: đang tải từ địa chỉ không phải https ($BASE_URL) — chỉ dùng khi thử nghiệm." >&2 ;;
esac
fetch() { curl "${CURL_OPTS[@]}" -o "$2" "$1"; }

# Kiem tra truoc khi tai: khong dung vao thu muc / lien ket khong phai cua aihot-vn.
is_our_skill_dir() {
  [ -f "$1/SKILL.md" ] && grep -q "^name: ${SKILL_NAME}\$" "$1/SKILL.md"
}
if [ -e "$DEST" ] || [ -L "$DEST" ]; then
  [ -d "$DEST" ] && [ ! -L "$DEST" ] || die "$DEST đã tồn tại nhưng không phải thư mục thường"
  if [ -n "$(ls -A "$DEST" 2>/dev/null)" ] && ! is_our_skill_dir "$DEST"; then
    die "$DEST đã có nội dung khác, không phải Skill $SKILL_NAME. Hãy kiểm tra rồi chọn --dir khác."
  fi
fi
if [ -n "$LINK" ]; then
  if [ -L "$LINK" ]; then
    CUR="$(readlink "$LINK")"
    [ "$CUR" = "$DEST" ] || die "$LINK đang trỏ tới $CUR. Hãy kiểm tra bản cũ rồi xóa liên kết này."
  elif [ -e "$LINK" ]; then
    die "$LINK đã tồn tại (không phải liên kết). Có thể là bản cài cũ: hãy kiểm tra, xóa rồi chạy lại, hoặc dùng --dir $LINK."
  fi
fi

PARENT="$(dirname "$DEST")"
mkdir -p "$PARENT"
TMP="$(mktemp -d "$PARENT/.${SKILL_NAME}.tmp.XXXXXX")"
cleanup() { rm -rf "$TMP"; }
trap cleanup EXIT

echo "Đang tải gói từ $BASE_URL ..."
fetch "$BASE_URL/manifest.sha256" "$TMP/manifest.sha256" || die "không tải được manifest.sha256"
mkdir -p "$TMP/pkg"
COUNT=0
while IFS= read -r LINE || [ -n "$LINE" ]; do
  case "$LINE" in ''|'#'*) continue ;; esac
  HASH="${LINE%% *}"
  FILE="${LINE#* }"
  FILE="${FILE# }"
  FILE="${FILE#\*}"
  printf '%s' "$HASH" | grep -Eq '^[0-9a-f]{64}$' || die "manifest.sha256 sai định dạng"
  case "$FILE" in
    ''|/*|*..*|*[!A-Za-z0-9._/-]*) die "đường dẫn không hợp lệ trong manifest: $FILE" ;;
  esac
  mkdir -p "$TMP/pkg/$(dirname "$FILE")"
  fetch "$BASE_URL/$FILE" "$TMP/pkg/$FILE" || die "không tải được $FILE"
  ACTUAL="$(sha256_of "$TMP/pkg/$FILE")"
  [ "$ACTUAL" = "$HASH" ] || die "sai SHA-256 ở $FILE — gói có thể đang được cập nhật, thử lại sau vài phút"
  COUNT=$((COUNT + 1))
done < "$TMP/manifest.sha256"

[ "$COUNT" -gt 0 ] || die "manifest.sha256 rỗng"
is_our_skill_dir "$TMP/pkg" || die "gói tải về không chứa SKILL.md của $SKILL_NAME"
cp "$TMP/manifest.sha256" "$TMP/pkg/manifest.sha256"

# Thay thu muc dich: doi ten ban cu sang thu muc tam roi dua ban moi vao.
if [ -d "$DEST" ]; then
  mv "$DEST" "$TMP/old"
fi
if ! mv "$TMP/pkg" "$DEST"; then
  [ -d "$TMP/old" ] && mv "$TMP/old" "$DEST"
  die "không thay được $DEST, đã giữ nguyên bản cũ"
fi

if [ -n "$LINK" ] && [ ! -L "$LINK" ]; then
  mkdir -p "$(dirname "$LINK")"
  ln -s "$DEST" "$LINK"
fi

VERSION="$(grep -m1 -E '^[[:space:]]*version:' "$DEST/SKILL.md" | awk '{print $2}')"
echo "Đã cài $SKILL_NAME ${VERSION:-} vào $DEST"
[ -z "$LINK" ] || echo "Liên kết cho Claude Code: $LINK -> $DEST"
echo "Hãy mở phiên Agent mới rồi hỏi thử: \"Trong 24 giờ qua giới AI có 5 việc gì quan trọng nhất?\""
