#!/bin/sh
set -eu
started_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
__GIT_MIRROR_PROXY_PRELUDE__
mkdir -p "$(dirname "$repo")"
if [ -d "$repo/objects" ] && [ -f "$repo/HEAD" ]; then
  git --git-dir="$repo" remote set-url origin "$remote" || git --git-dir="$repo" remote add origin "$remote"
else
  rm -rf "$repo"
  git init --bare "$repo"
  git --git-dir="$repo" remote add origin "$remote"
fi
git --git-dir="$repo" config uploadpack.allowReachableSHA1InWant true
git --git-dir="$repo" config uploadpack.allowAnySHA1InWant true
git --git-dir="$repo" config http.uploadpack true
git --git-dir="$repo" config http.receivepack true
timeout 240 git --git-dir="$repo" fetch origin "+refs/heads/${source_branch}:refs/mirror-stage/heads/${source_branch}"
source_sha=$(git --git-dir="$repo" rev-parse --verify "refs/mirror-stage/heads/${source_branch}^{commit}")
source_stage_ref="${source_stage_ref_prefix%/}/$source_sha"
git --git-dir="$repo" update-ref "$source_stage_ref" "$source_sha"
git --git-dir="$repo" update-ref "refs/heads/${source_branch}" "$source_sha"
discarded_stale_gitops=false
if timeout 240 git --git-dir="$repo" fetch origin "+refs/heads/${gitops_branch}:refs/mirror-stage/heads/${gitops_branch}"; then
  github_gitops=$(git --git-dir="$repo" rev-parse --verify "refs/mirror-stage/heads/${gitops_branch}^{commit}" 2>/dev/null || true)
  local_gitops=$(git --git-dir="$repo" rev-parse --verify "refs/heads/${gitops_branch}^{commit}" 2>/dev/null || true)
  if [ -z "$local_gitops" ] && [ -n "$github_gitops" ]; then
    git --git-dir="$repo" update-ref "refs/heads/${gitops_branch}" "$github_gitops"
  elif [ -n "$local_gitops" ] && [ -n "$github_gitops" ] && [ "$local_gitops" != "$github_gitops" ] && git --git-dir="$repo" merge-base --is-ancestor "$local_gitops" "$github_gitops"; then
    git --git-dir="$repo" update-ref "refs/heads/${gitops_branch}" "$github_gitops"
  elif [ -n "$local_gitops" ] && [ -n "$github_gitops" ] && [ "$local_gitops" != "$github_gitops" ] && [ "${UNIDESK_GIT_MIRROR_DISCARD_STALE_GITOPS:-false}" = "true" ]; then
    git --git-dir="$repo" update-ref "refs/heads/${gitops_branch}" "$github_gitops"
    discarded_stale_gitops=true
    printf '%s\n' "git-mirror sync: discarded stale local gitops ref local=${local_gitops} github=${github_gitops}" >&2
  fi
fi
git --git-dir="$repo" update-server-info
export repository source_branch source_stage_ref gitops_branch started_at discarded_stale_gitops
summary_tmp=/tmp/HWLAB.last-sync.json.$$
node <<'NODE' > "$summary_tmp"
const { execFileSync } = require('node:child_process');
const repository = process.env.repository;
const sourceBranch = process.env.source_branch;
const gitopsBranch = process.env.gitops_branch;
const repoPath = `/cache/${repository}.git`;
function rev(ref) { try { return execFileSync('git', ['--git-dir=' + repoPath, 'rev-parse', '--verify', ref + '^{commit}'], { encoding: 'utf8' }).trim(); } catch { return null; } }
const localSource = rev(`refs/heads/${sourceBranch}`);
const githubSource = rev(`refs/mirror-stage/heads/${sourceBranch}`);
const sourceStageRef = process.env.source_stage_ref;
const sourceSnapshot = sourceStageRef ? rev(sourceStageRef) : null;
const localGitops = rev(`refs/heads/${gitopsBranch}`);
const githubGitops = rev(`refs/mirror-stage/heads/${gitopsBranch}`);
const pendingFlush = Boolean(localGitops && (!githubGitops || localGitops !== githubGitops));
console.log(JSON.stringify({ event: 'git-mirror-sync', repo: repository, status: 'succeeded', startedAt: process.env.started_at, syncedAt: new Date().toISOString(), sourceAuthority: 'git-mirror-snapshot', localSource, githubSource, sourceStageRef, sourceSnapshot, gitopsBranch, localGitops, githubGitops, sourceInSync: Boolean(localSource && githubSource && localSource === githubSource && sourceSnapshot === githubSource), gitopsInSync: Boolean(localGitops && githubGitops && localGitops === githubGitops), pendingFlush, discardedStaleGitops: process.env.discarded_stale_gitops === 'true' }));
NODE
tee /cache/HWLAB.last-sync.json < "$summary_tmp"
rm -f "$summary_tmp"
