#!/usr/bin/env bash
# dingclaw 工作域统一入口。全部子命令只读。
#
# 这是产品骨架，不含任何个人数据：一切路径都从环境变量取，缺省值按 XDG 惯例。
set -euo pipefail

DINGCLAW_HOME="${DINGCLAW_HOME:-$HOME/.dingclaw}"
DINGCLAW_CONFIG="${DINGCLAW_CONFIG:-${XDG_CONFIG_HOME:-$HOME/.config}/dingclaw/config.json}"
DINGCLAW_STATE="${DINGCLAW_STATE:-${XDG_STATE_HOME:-$HOME/.local/state}/dingclaw/state.db}"
DINGCLAWD="${DINGCLAWD:-$(command -v dingclawd || true)}"
DWS="${DWS_BIN:-$(command -v dws || true)}"

usage() {
  cat <<'EOF'
dingclaw — 钉钉数字分身工作域入口（全部只读）

  dingclaw role            打印角色定义（IDENTITY + SOUL）
  dingclaw skill [tier]    打印该档位实际拼出的 skill 全文
                           tier: restricted(默认) | standard | privileged
  dingclaw who <关键词>     查同事：花名/姓名 -> userId + openDingTalkId
  dingclaw roster          打印 standard 白名单当前生效名单
  dingclaw status          分身运行状态（门禁 + 待发送 + 最近轮询）
  dingclaw doctor          分身健康检查
  dingclaw tui [--hours N] 打开面板（收件箱 / 会话 / 时间线），N 缺省 24

环境变量：
  DINGCLAW_HOME    工作域目录        (默认 ~/.dingclaw)
  DINGCLAW_CONFIG  服务配置          (默认 ~/.config/dingclaw/config.json)
  DINGCLAW_STATE   状态库            (默认 ~/.local/state/dingclaw/state.db)
  DINGCLAWD        服务 CLI 路径      (默认从 PATH 查找)
  DWS_BIN          DWS CLI 路径       (默认从 PATH 查找)
  DWS_PROFILE      组织 corpId        (默认从配置读取)
EOF
}

die() { echo "$*" >&2; exit 1; }

need_dingclawd() {
  [ -n "$DINGCLAWD" ] || die "找不到 dingclawd。装好包后重试，或设置 DINGCLAWD=<绝对路径>。"
}

config_value() {
  python3 -c '
import json, sys
try:
    with open(sys.argv[1], encoding="utf-8") as handle:
        print(json.load(handle).get(sys.argv[2], "") or "")
except OSError:
    print("")
' "$DINGCLAW_CONFIG" "$1"
}

cmd_role() {
  for name in IDENTITY.md SOUL.md; do
    [ -f "$DINGCLAW_HOME/$name" ] || continue
    echo "########## $name ##########"
    cat "$DINGCLAW_HOME/$name"
    echo
  done
}

cmd_skill() {
  need_dingclawd
  local tier="${1:-restricted}"
  "$(dirname "$DINGCLAWD")/python" - "$tier" "$DINGCLAW_CONFIG" <<'PY'
import sys
from pathlib import Path

from dingclaw.config import load_config
from dingclaw.context import load_skill_bundle, utf8_length

tier, config_path = sys.argv[1], sys.argv[2]
config = load_config(Path(config_path).expanduser())
bundle = load_skill_bundle(config.skill_path)
packs = config.skill_packs_for(tier)
text = bundle.instructions_for("在吗", allowed_packs=packs)
print(f"# tier={tier} packs={packs} bytes={utf8_length(text)}", file=sys.stderr)
print(text)
PY
}

cmd_who() {
  [ $# -ge 1 ] || die "用法: dingclaw who <关键词>"
  [ -n "$DWS" ] || die "找不到 dws。设置 DWS_BIN=<绝对路径>。"
  local profile="${DWS_PROFILE:-$(config_value dws_profile)}"
  [ -n "$profile" ] || die "取不到 dws profile。设置 DWS_PROFILE，或先配好 config.json。"
  "$DWS" contact user search --query "$1" --profile "$profile" --format json \
    | python3 -c '
import json, sys
rows = json.load(sys.stdin).get("result") or []
if not rows:
    print("(查无此人)")
for row in rows:
    print("%-8s %-10s userId=%-12s open=%s" % (
        row.get("flowerName") or "-",
        row.get("name") or "",
        row.get("userId") or "",
        row.get("openDingTalkId") or "",
    ))
'
}

cmd_roster() {
  python3 -c '
import json, sys
try:
    with open(sys.argv[1], encoding="utf-8") as handle:
        config = json.load(handle)
except OSError as error:
    sys.exit(f"读不到配置: {error}")
standard = config.get("tier_standard_user_ids") or []
deny = config.get("deny_user_ids") or []
print(f"standard 白名单 {len(standard)} 项（userId 与 openDingTalkId 各算一项）:")
for item in standard:
    print(f"  {item}")
print(f"\n黑名单 {len(deny)} 项:")
for item in deny:
    print(f"  {item}")
print("\n注意：入站消息 sender_id 恒为空，白名单必须含 openDingTalkId 才会命中。")
' "$DINGCLAW_CONFIG"
}

cmd_status() { need_dingclawd; "$DINGCLAWD" status --config "$DINGCLAW_CONFIG"; }
cmd_doctor() { need_dingclawd; "$DINGCLAWD" doctor --config "$DINGCLAW_CONFIG"; }
# The only subcommand here that is not read-only and not a one-shot: it hands
# the terminal to the panel until the reader quits. exec rather than a child,
# so Ctrl-C and the window size reach the panel and not this wrapper.
cmd_tui() { need_dingclawd; exec "$DINGCLAWD" tui --config "$DINGCLAW_CONFIG" "$@"; }

case "${1:-}" in
  role)   shift; cmd_role "$@" ;;
  skill)  shift; cmd_skill "$@" ;;
  who)    shift; cmd_who "$@" ;;
  roster) shift; cmd_roster "$@" ;;
  status) shift; cmd_status "$@" ;;
  doctor) shift; cmd_doctor "$@" ;;
  tui)    shift; cmd_tui "$@" ;;
  ""|-h|--help|help) usage ;;
  *) usage; exit 2 ;;
esac
