#!/usr/bin/env bash
# 共享 dm-server 薄入口：读取 deps/development-manager 的 gitlink 钉住提交，
# 按该提交构建并缓存 dm-server，再 exec 其子命令（agent-exec、task、governance）。执行语义与退出码以该二进制为准。
set -euo pipefail

root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)
dm="$root/deps/development-manager"

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

# 1. 钉住版本只来自索引中的 gitlink（mode 160000），不读取工作区文件。
entry=$(git -C "$root" ls-files -s -- deps/development-manager 2>/dev/null || true)
[ -n "$entry" ] || die "索引中缺少 deps/development-manager 的 gitlink，无法确定钉住的 DM 版本"
read -r mode pin _stage _path <<<"$entry"
[ "$mode" = 160000 ] || die "deps/development-manager 不是 gitlink（mode=$mode）"
[[ "$pin" =~ ^[0-9a-f]{40}$ ]] || die "gitlink 提交格式无效：$pin"

# 2. 检出必须存在且确为 DM 独立仓库（避免 git -C 误解析到外层仓库），HEAD 必须等于钉住提交。
[ -e "$dm/.git" ] || die "deps/development-manager 未检出；请按钉住提交 $pin 检出该 gitlink"
top=$(git -C "$dm" rev-parse --show-toplevel 2>/dev/null || true)
[ -n "$top" ] && [ "$top" = "$(cd "$dm" && pwd -P)" ] \
  || die "deps/development-manager 不是独立检出；请按钉住提交 $pin 检出该 gitlink"
head=$(git -C "$dm" rev-parse HEAD 2>/dev/null || true)
[ "$head" = "$pin" ] \
  || die "deps/development-manager HEAD（${head:-未知}）与钉住提交 $pin 不一致；请按钉住提交检出"

# 3. 检出工作树必须干净（忽略嵌套 submodule 状态）。
dirty=$(git -C "$dm" status --porcelain --ignore-submodules=all) \
  || die "无法读取 deps/development-manager 的工作树状态"
[ -z "$dirty" ] || die "deps/development-manager 存在未提交改动，拒绝运行（请先清理该检出）"

# 4. 二进制按钉住提交缓存；缺失时在缓存目录内临时构建，完成后原子改名，避免留下半成品。
cache="${DM_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/development-manager/dm-server}"
bin="$cache/dm-server-$pin"
if [ ! -x "$bin" ]; then
  command -v go >/dev/null 2>&1 || die "缺少 go，无法构建 dm-server（$pin）"
  mkdir -p "$cache"
  cache=$(cd "$cache" && pwd -P)
  bin="$cache/dm-server-$pin"
  work=$(mktemp -d "$cache/build-$pin.XXXXXX")
  if ! (cd "$dm" && go build -trimpath -o "$work/dm-server" ./cmd/dm-server); then
    rm -rf "$work"
    die "构建 dm-server 失败（$pin）"
  fi
  mv -f "$work/dm-server" "$bin"
  rm -rf "$work"
fi

exec "$bin" "$@"
