#!/usr/bin/env zsh

set -eu

for cmd in git sops openssl; do
  if ! command -v "${cmd}" >/dev/null 2>&1; then
    echo "check-sops-sync: required command missing: ${cmd}" >&2
    exit 1
  fi
done

if [ -z "${SOPS_SYNC_HMAC_KEY:-}" ]; then
  echo "check-sops-sync: SOPS_SYNC_HMAC_KEY is required" >&2
  exit 1
fi

repo_root=$(git rev-parse --show-toplevel)
regex_script="${repo_root}/scripts/lib/sops-path-regexes"
lib_script="${repo_root}/scripts/lib/sops-sync-lib"

if [ ! -x "${regex_script}" ]; then
  echo "check-sops-sync: missing helper ${regex_script}" >&2
  exit 1
fi

if [ ! -f "${lib_script}" ]; then
  echo "check-sops-sync: missing helper ${lib_script}" >&2
  exit 1
fi

. "${lib_script}"

regexes=("${(@f)$("${regex_script}")}")
fail=0

while IFS= read -r tracked_path; do
  [ -n "${tracked_path}" ] || continue
  [[ "${tracked_path}" == *.enc.* ]] || continue

  if ! matches_any_rule "${tracked_path}" "${regexes[@]}"; then
    continue
  fi

  sidecar_path=$(hmac_sidecar_for_enc "${tracked_path}")

  if ! git ls-files --error-unmatch -- "${sidecar_path}" >/dev/null 2>&1; then
    echo "check-sops-sync: missing sync sidecar for ${tracked_path}" >&2
    fail=1
    continue
  fi

  if ! is_sops_encrypted_file "${tracked_path}"; then
    echo "check-sops-sync: file is not valid SOPS-encrypted content: ${tracked_path}" >&2
    fail=1
    continue
  fi

  sidecar_value=$(read_sidecar "${sidecar_path}" || true)
  if [ -z "${sidecar_value}" ]; then
    echo "check-sops-sync: sidecar is empty: ${sidecar_path}" >&2
    fail=1
    continue
  fi

  if ! computed_hmac=$(decrypt_enc_to_plain "${tracked_path}" | compute_hmac_for_stdin); then
    echo "check-sops-sync: failed to decrypt ${tracked_path}" >&2
    fail=1
    continue
  fi

  if [ "${computed_hmac}" != "${sidecar_value}" ]; then
    echo "check-sops-sync: decrypted plaintext HMAC does not match sidecar for ${tracked_path}" >&2
    fail=1
  fi
done < <(git ls-files)

exit "${fail}"
