#!/usr/bin/env bash
# bithot Agent Skill 安装器：下载三个文件、校验 SHA-256，再写入目标目录。

set -euo pipefail
BASE="https://bithot.news/bithot-skill"
SKILL_ID="bithot"
ORIGIN="https://bithot.news"
HASH_SKILL="413ec2180b9362c9bdd7a362226338d3607505dc320533c4b54805ffb429b7f0"
HASH_LICENSE="590ecf513d59304812a22609b27e6ef086088375ec184aaf22d98c99ff628e6d"
HASH_YAML="8328163b7b48cd71c305fc0f79304846c7f5d62949dc5db1b4de00f12ee96ced"

usage() {
  echo "用法: $0 --target agents|claude   或   $0 --dir <目录>"
  echo "  --target agents   装到 ~/.agents/skills/${SKILL_ID}"
  echo "  --target claude   同上，并在 ~/.claude/skills/${SKILL_ID} 建软链"
  echo "  --dir <路径>      装到指定目录"
  echo "  --actor <uuid>    写入匿名去重标识（与接入页复制的一致）"
  echo "  --no-actor        不生成匿名去重标识"
  exit 2
}

TARGET=""
DIR=""
NO_ACTOR=0
ACTOR_VALUE=""
while [[ $# -gt 0 ]]; do
  case "$1" in
    --target) TARGET="${2:-}"; shift 2 ;;
    --dir) DIR="${2:-}"; shift 2 ;;
    --actor) ACTOR_VALUE="${2:-}"; shift 2 ;;
    --no-actor) NO_ACTOR=1; shift ;;
    -h|--help) usage ;;
    *) echo "未知参数: $1"; usage ;;
  esac
done

if [[ -z "$DIR" ]]; then
  [[ -n "$TARGET" ]] || usage
  DIR="$HOME/.agents/skills/$SKILL_ID"
fi

# --actor 与 --no-actor 互斥
if [[ "$NO_ACTOR" -eq 1 && -n "$ACTOR_VALUE" ]]; then
  echo "不能同时使用 --actor 与 --no-actor" >&2
  exit 2
fi

# 校验传入的 actor 形态
if [[ -n "$ACTOR_VALUE" ]]; then
  if [[ ! "$ACTOR_VALUE" =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ ]]; then
    echo "--actor 需要 UUID v4" >&2
    exit 2
  fi
  ACTOR_VALUE="$(printf '%s' "$ACTOR_VALUE" | tr '[:upper:]' '[:lower:]')"
fi

hash_of() {
  # 从 stdin 读文件内容再算哈希：Windows Git Bash 下路径常含反斜杠，
  # sha256sum 会给输出行加 \ 前缀，awk 取到的就不是纯哈希，从而假报「校验失败」。
  # 走 stdin 后输出形如「hash  -」，不绕过任何校验，只避开路径转义。
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum < "$1" | awk '{print $1}' # 取第一列十六进制摘要
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 < "$1" | awk '{print $1}' # macOS 等无 sha256sum 时的后备
  else
    echo "缺少 sha256sum 或 shasum" >&2 # 两样都没有则无法安装
    exit 1
  fi
}

if ! command -v curl >/dev/null 2>&1; then
  echo "缺少 curl" >&2
  exit 1
fi

# 目录里已有别家 Skill 时停手，避免覆盖
if [[ -f "$DIR/SKILL.md" ]] && ! grep -qE "^name:[[:space:]]*${SKILL_ID}[[:space:]]*$" "$DIR/SKILL.md"; then
  echo "目录 $DIR 已有其它 Skill（SKILL.md 的 name 不是 ${SKILL_ID}），请换目录或手动处理" >&2
  exit 1
fi

# Git Bash 默认 TEMP 常落在 D:\Temp：mktemp 路径带反斜杠，旧版用「sha256sum 文件路径」会假失败。
# 能写 /tmp 时优先用它（与 TMPDIR=/tmp 重跑等价）；新版 hash_of 已改 stdin，这里仍降低踩坑面。
if [[ -d /tmp && -w /tmp ]]; then
  case "${TMPDIR:-}" in
    ""|*[\\:]*|/tmp) export TMPDIR=/tmp ;; # 空、Windows 盘符路径、或已是 /tmp
  esac
fi
TMP="$(mktemp -d)" # 临时目录，退出时删掉
cleanup() { rm -rf "$TMP"; } # 清理函数
trap cleanup EXIT # 正常/异常退出都清理
mkdir -p "$TMP/agents" # 放 openai.yaml 的子目录

curl -fsSL "$BASE/SKILL.md" -o "$TMP/SKILL.md"
curl -fsSL "$BASE/LICENSE" -o "$TMP/LICENSE"
curl -fsSL "$BASE/agents/openai.yaml" -o "$TMP/agents/openai.yaml"

[[ "$(hash_of "$TMP/SKILL.md")" == "$HASH_SKILL" ]] || { echo "SKILL.md 校验失败"; exit 1; }
[[ "$(hash_of "$TMP/LICENSE")" == "$HASH_LICENSE" ]] || { echo "LICENSE 校验失败"; exit 1; }
[[ "$(hash_of "$TMP/agents/openai.yaml")" == "$HASH_YAML" ]] || { echo "openai.yaml 校验失败"; exit 1; }

mkdir -p "$DIR/agents"
cp "$TMP/SKILL.md" "$TMP/LICENSE" "$DIR/"
cp "$TMP/agents/openai.yaml" "$DIR/agents/"

ACTOR="$DIR/.$SKILL_ID-actor-id"
if [[ "$NO_ACTOR" -eq 0 ]]; then
  if [[ -n "$ACTOR_VALUE" ]]; then
    printf '%s\n' "$ACTOR_VALUE" > "$ACTOR"
    chmod 600 "$ACTOR"
  elif [[ ! -f "$ACTOR" ]]; then
    if command -v uuidgen >/dev/null 2>&1; then
      uuidgen | tr '[:upper:]' '[:lower:]' > "$ACTOR"
    else
      python3 -c 'import uuid; print(uuid.uuid4())' > "$ACTOR"
    fi
    chmod 600 "$ACTOR"
  fi
fi
printf '.*-actor-id\n.gitignore\n' > "$DIR/.gitignore"

if [[ "$TARGET" == "claude" ]]; then
  mkdir -p "$HOME/.claude/skills"
  ln -sfn "$DIR" "$HOME/.claude/skills/$SKILL_ID"
fi

echo "已安装 $SKILL_ID 到 $DIR"
echo "请开一个新会话，再问：过去 24 小时加密圈最重要的 5 件事是什么？"
echo "站点: $ORIGIN"
