#!/bin/sh
set -eu
repo_url="ssh://git@ssh.github.com:443/pikasTech/HWLAB.git"
repo_path="/cache/pikasTech/HWLAB.git"
lock_dir="/cache/.hwlab-flush.lock"
started_ms=$(node -e 'console.log(Date.now())')
now_ms() { node -e 'console.log(Date.now())'; }
emit_timing() {
  phase="$1"
  status="$2"
  started="$3"
  finished=$(now_ms)
  duration=$((finished - started))
  printf '{"event":"git-mirror-flush-timing","phase":"%s","status":"%s","durationMs":%s,"repository":"pikasTech/HWLAB"}
' "$phase" "$status" "$duration"
}
if ! mkdir "$lock_dir" 2>/dev/null; then
  echo "git mirror flush already running"
  exit 0
fi
trap 'rmdir "$lock_dir" 2>/dev/null || true' EXIT INT TERM
mkdir -p /root/.ssh
cp /git-ssh/ssh-privatekey /root/.ssh/id_rsa
chmod 0400 /root/.ssh/id_rsa
# __HWLAB_GIT_MIRROR_SSH_PRELUDE__
/script/install-hooks.sh
for gitops_branch in __HWLAB_GITOPS_BRANCH_ARGS__; do
  local_head=$(git -C "$repo_path" show-ref --verify --hash "refs/heads/$gitops_branch" 2>/dev/null || true)
  if [ -z "$local_head" ]; then
    echo "git mirror flush skips missing local refs/heads/$gitops_branch"
    continue
  fi
  fetch_started=$(now_ms)
  timeout 90 git -C "$repo_path" fetch --quiet "$repo_url" "refs/heads/$gitops_branch:refs/mirror-stage/heads/$gitops_branch"
  emit_timing "fetch-$gitops_branch" succeeded "$fetch_started"
  github_head=$(git -C "$repo_path" show-ref --verify --hash "refs/mirror-stage/heads/$gitops_branch" 2>/dev/null || true)
  if [ -n "$github_head" ] && [ "$github_head" != "$local_head" ] && ! git -C "$repo_path" merge-base --is-ancestor "$github_head" "$local_head"; then
    echo "git mirror flush rejected divergent $gitops_branch local=$local_head github=$github_head" >&2
    exit 52
  fi
  if [ "$local_head" != "$github_head" ]; then
    push_started=$(now_ms)
    timeout 120 git -C "$repo_path" push "$repo_url" "$local_head:refs/heads/$gitops_branch"
    emit_timing "push-$gitops_branch" succeeded "$push_started"
  else
    echo "git mirror flush $gitops_branch already matches GitHub"
  fi
  git -C "$repo_path" update-ref "refs/mirror-stage/heads/$gitops_branch" "$local_head"
done
git -C "$repo_path" update-server-info
flushed_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
export flushed_at
export gitops_branches_json=__HWLAB_GITOPS_BRANCHES_JSON_SHELL__
node - <<'NODE' | tee /cache/HWLAB.last-flush.json
const { execFileSync } = require("node:child_process");
const repo = "/cache/pikasTech/HWLAB.git";
const gitopsBranches = JSON.parse(process.env.gitops_branches_json || "[]");
function rev(ref) {
  try { return execFileSync("git", ["-C", repo, "rev-parse", ref], { encoding: "utf8" }).trim() || null; } catch { return null; }
}
const refs = {};
for (const branch of gitopsBranches) {
  refs["refs/heads/" + branch] = rev("refs/heads/" + branch);
  refs["refs/mirror-stage/heads/" + branch] = rev("refs/mirror-stage/heads/" + branch);
}
const pendingFlush = gitopsBranches.some((branch) => refs["refs/heads/" + branch] && refs["refs/mirror-stage/heads/" + branch] && refs["refs/heads/" + branch] !== refs["refs/mirror-stage/heads/" + branch]);
console.log(JSON.stringify({
  event: "git-mirror-flush",
  status: "flushed",
  repository: "pikasTech/HWLAB",
  flushedAt: process.env.flushed_at,
  pendingFlush,
  refs
}));
NODE
emit_timing total succeeded "$started_ms"
