#!/usr/bin/env bash
# Verify one Gitea bundle can be restored into a temporary mirror clone.
# This is a dry-run verifier only. It does not restore into production, mutate
# Gitea, read credentials, delete repositories, or change repo visibility.

set -euo pipefail

ROOT="${AIOPS_GITEA_BUNDLE_ROOT:-/home/ollama/backup/110/gitea/git-bundles/latest-private-complete}"
REPO="${AIOPS_GITEA_BUNDLE_SAMPLE_REPO:-wooo/awoooi}"
HOST_LABEL="${AIOPS_HOST_LABEL:-188}"
TEXTFILE_PATH="${AIOPS_GITEA_BUNDLE_RESTORE_TEXTFILE:-/home/ollama/node_exporter_textfiles/gitea_bundle_restore_dry_run.prom}"
WRITE_TEXTFILE=0
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-120}"

usage() {
  cat <<'USAGE'
Usage: scripts/backup/gitea-bundle-sample-restore-dry-run.sh [options]

Options:
  --root PATH          Bundle root directory.
  --repo OWNER/NAME    Repository sample to verify. Default: wooo/awoooi.
  --write-textfile     Write node-exporter textfile metric after verification.
  --textfile PATH      Textfile metric path.
  -h, --help           Show this help.

This verifier clones the bundle into a temporary mirror and runs git fsck.
It never restores to production, never contacts Gitea, and never reads tokens.
USAGE
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --root)
      shift
      ROOT="${1:?--root requires PATH}"
      ;;
    --repo)
      shift
      REPO="${1:?--repo requires OWNER/NAME}"
      ;;
    --write-textfile)
      WRITE_TEXTFILE=1
      ;;
    --textfile)
      shift
      TEXTFILE_PATH="${1:?--textfile requires PATH}"
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown argument: $1" >&2
      usage >&2
      exit 64
      ;;
  esac
  shift
done

slug="${REPO//\//__}"
repo_name="${REPO##*/}"
bundle_path=""
checksum_path=""

if [ -f "${ROOT}/${slug}.bundle" ]; then
  bundle_path="${ROOT}/${slug}.bundle"
elif [ -f "${ROOT}/manifest.remote.tsv" ] || [ -f "${ROOT}/manifest.tsv" ]; then
  manifest="${ROOT}/manifest.remote.tsv"
  [ -f "$manifest" ] || manifest="${ROOT}/manifest.tsv"
  bundle_path="$(awk -F '\t' -v repo="$REPO" 'NR > 1 && $1 == repo {print $4; exit}' "$manifest")"
  if [ -n "$bundle_path" ] && [ ! -f "$bundle_path" ] && [ -f "${ROOT}/$(basename "$bundle_path")" ]; then
    bundle_path="${ROOT}/$(basename "$bundle_path")"
  fi
fi

if [ -z "$bundle_path" ] || [ ! -f "$bundle_path" ]; then
  first_match="$(find "$ROOT" -maxdepth 1 -type f -name "${repo_name}-local-*.bundle" | sort | tail -n 1)"
  bundle_path="$first_match"
fi

ok=0
ref_count=0
error_reason=""
tmp_root=""

if [ -z "$bundle_path" ] || [ ! -f "$bundle_path" ]; then
  error_reason="bundle_not_found"
else
  checksum_path="${bundle_path}.sha256"
  if [ -f "$checksum_path" ]; then
    expected="$(awk 'NR == 1 {print $1}' "$checksum_path")"
    if command -v sha256sum >/dev/null 2>&1; then
      actual="$(sha256sum "$bundle_path" | awk '{print $1}')"
    else
      actual="$(shasum -a 256 "$bundle_path" | awk '{print $1}')"
    fi
    if [ "$expected" != "$actual" ]; then
      error_reason="checksum_mismatch"
    fi
  fi
fi

if [ -z "$error_reason" ]; then
  tmp_root="$(mktemp -d "${TMPDIR:-/tmp}/gitea-bundle-restore.XXXXXX")"
  trap 'rm -rf "$tmp_root"' EXIT
  if ! timeout "$TIMEOUT_SECONDS" git clone --mirror --quiet "$bundle_path" "${tmp_root}/restore.git"; then
    error_reason="clone_failed"
  elif ! timeout "$TIMEOUT_SECONDS" git -C "${tmp_root}/restore.git" fsck --connectivity-only >/dev/null; then
    error_reason="fsck_failed"
  else
    ref_count="$(git -C "${tmp_root}/restore.git" for-each-ref --format='%(refname)' | wc -l | tr -d ' ')"
    ok=1
  fi
fi

timestamp="$(date +%s)"
bundle_name="$(basename "${bundle_path:-missing}")"
root_label="${ROOT//\\/\\\\}"
root_label="${root_label//\"/\\\"}"
repo_label="${REPO//\\/\\\\}"
repo_label="${repo_label//\"/\\\"}"
bundle_label="${bundle_name//\\/\\\\}"
bundle_label="${bundle_label//\"/\\\"}"
error_label="${error_reason//\\/\\\\}"
error_label="${error_label//\"/\\\"}"

if [ "$WRITE_TEXTFILE" -eq 1 ]; then
  mkdir -p "$(dirname "$TEXTFILE_PATH")"
  tmp_textfile="${TEXTFILE_PATH}.$$"
  {
    echo '# HELP awoooi_gitea_bundle_sample_restore_dry_run_ok Whether sample Gitea bundle restore dry-run succeeded.'
    echo '# TYPE awoooi_gitea_bundle_sample_restore_dry_run_ok gauge'
    printf 'awoooi_gitea_bundle_sample_restore_dry_run_ok{host="%s",repo="%s",root="%s",bundle="%s",error="%s"} %s\n' "$HOST_LABEL" "$repo_label" "$root_label" "$bundle_label" "$error_label" "$ok"
    printf 'awoooi_gitea_bundle_sample_restore_dry_run_timestamp{host="%s",repo="%s"} %s\n' "$HOST_LABEL" "$repo_label" "$timestamp"
    printf 'awoooi_gitea_bundle_sample_restore_dry_run_ref_count{host="%s",repo="%s"} %s\n' "$HOST_LABEL" "$repo_label" "$ref_count"
  } > "$tmp_textfile"
  mv "$tmp_textfile" "$TEXTFILE_PATH"
fi

printf 'GITEA_BUNDLE_SAMPLE_RESTORE_DRY_RUN_OK=%s\n' "$ok"
printf 'REPO=%s\n' "$REPO"
printf 'BUNDLE=%s\n' "${bundle_path:-missing}"
printf 'REF_COUNT=%s\n' "$ref_count"
printf 'TEXTFILE_WRITTEN=%s\n' "$WRITE_TEXTFILE"
if [ -n "$error_reason" ]; then
  printf 'ERROR=%s\n' "$error_reason"
  exit 1
fi
