#!/usr/bin/env bash
set -euo pipefail

identity_is_valid() {
  local path="$1"
  if [[ -z "$path" || ! -f "$path" || ! -s "$path" ]]; then
    return 1
  fi

  chmod 600 "$path" 2>/dev/null || true
  if command -v age-keygen >/dev/null 2>&1 && age-keygen -y "$path" >/dev/null 2>&1; then
    return 0
  fi
  if openssh_private_identity_has_markers "$path"; then
    return 0
  fi
  if command -v ssh-keygen >/dev/null 2>&1 && ssh-keygen -y -f "$path" >/dev/null 2>&1; then
    return 0
  fi

  local header
  header="$(LC_ALL=C head -c 80 "$path" 2>/dev/null || true)"
  case "$header" in
    AGE-SECRET-KEY-*) return 0 ;;
  esac

  echo "::warning ::Ignoring invalid age identity candidate at ${path}" >&2
  return 1
}

openssh_private_identity_has_markers() {
  local path="$1"
  local first_line
  first_line="$(LC_ALL=C sed -n '1p' "$path" 2>/dev/null || true)"
  if [[ "$first_line" != "-----BEGIN OPENSSH PRIVATE KEY-----" ]]; then
    return 1
  fi
  if LC_ALL=C grep -Fq '\n' "$path" 2>/dev/null; then
    return 1
  fi
  LC_ALL=C grep -q '^-----END OPENSSH PRIVATE KEY-----$' "$path" 2>/dev/null
}

candidate_path() {
  local path="$1"
  if identity_is_valid "$path"; then
    printf '%s\n' "$path"
    return 0
  fi
  return 1
}

preferred_home() {
  if [[ -n "${RUNNER_HOME:-}" ]]; then
    printf '%s\n' "$RUNNER_HOME"
  elif [[ -n "${FORGEJO_RUNNER_HOME:-}" ]]; then
    printf '%s\n' "$FORGEJO_RUNNER_HOME"
  elif [[ -n "${HOME:-}" ]]; then
    printf '%s\n' "$HOME"
  elif [[ -n "${FORGEJO_RUNNER_WORKDIR:-}" ]]; then
    printf '%s\n' "${FORGEJO_RUNNER_WORKDIR}/home"
  else
    printf '%s\n' "/tmp/forgejo-runner/home"
  fi
}

decode_base64() {
  local value="$1"
  local path="$2"
  if command -v base64 >/dev/null 2>&1; then
    if printf '%s' "$value" | base64 -d > "$path" 2>/dev/null; then
      return 0
    fi
    if printf '%s' "$value" | base64 -D > "$path" 2>/dev/null; then
      return 0
    fi
  fi
  return 1
}

materialize_secret() {
  local raw="$1"
  local home="$2"
  local path="${home}/.ssh/age_keystore"
  install -d -m 700 "${home}/.ssh"
  printf '%s\n' "$raw" > "$path"
  perl -0pi -e 's/\r\n?/\n/g' "$path" 2>/dev/null || true
  chmod 600 "$path"
  if identity_is_valid "$path"; then
    printf '%s\n' "$path"
    return 0
  fi

  if [[ "$raw" == *"\\n"* ]]; then
    printf '%b' "$raw" > "$path"
    perl -0pi -e 's/\r\n?/\n/g' "$path" 2>/dev/null || true
    chmod 600 "$path"
    if identity_is_valid "$path"; then
      printf '%s\n' "$path"
      return 0
    fi
  fi

  if decode_base64 "$raw" "$path"; then
    perl -0pi -e 's/\r\n?/\n/g' "$path" 2>/dev/null || true
    chmod 600 "$path"
    if identity_is_valid "$path"; then
      printf '%s\n' "$path"
      return 0
    fi
  fi

  rm -f "$path"
  echo "::warning ::Injected age identity was present but not parseable; trying other candidates" >&2
  return 1
}

resolve_from_existing_files() {
  local home
  home="$(preferred_home)"

  local candidate
  while IFS= read -r candidate; do
    candidate_path "$candidate" && return 0
  done <<EOF
${AGE_IDENTITY_PATH:-}
${BURROW_RUNNER_AGE_IDENTITY_PATH:-}
/var/lib/forgejo-runner-agent/age_keystore
EOF

  if [[ -n "${BURROW_RUNNER_AGE_IDENTITY_B64:-}" ]]; then
    local decoded_path
    decoded_path="${home}/.ssh/age_keystore.from_b64"
    if decode_base64 "$BURROW_RUNNER_AGE_IDENTITY_B64" "$decoded_path" && candidate_path "$decoded_path"; then
      return 0
    fi
    rm -f "$decoded_path"
    if materialize_secret "$BURROW_RUNNER_AGE_IDENTITY_B64" "$home"; then
      return 0
    fi
  fi

  if [[ -n "${BURROW_RUNNER_AGE_IDENTITY:-}" ]]; then
    materialize_secret "$BURROW_RUNNER_AGE_IDENTITY" "$home" && return 0
  fi

  if [[ -n "${AGE_FORGE_SSH_KEY:-}" ]]; then
    materialize_secret "$AGE_FORGE_SSH_KEY" "$home" && return 0
  fi

  while IFS= read -r candidate; do
    candidate_path "$candidate" && return 0
  done <<EOF
${RUNNER_HOME:-}/.ssh/age_keystore
${FORGEJO_RUNNER_HOME:-}/.ssh/age_keystore
${HOME:-}/.ssh/age_keystore
${FORGEJO_RUNNER_WORKDIR:-}/home/.ssh/age_keystore
${FORGEJO_RUNNER_WORKDIR:-}/age_keystore
/tmp/forgejo-runner/home/.ssh/age_keystore
/tmp/forgejo-runner/age_keystore
EOF

  return 1
}

if resolved="$(resolve_from_existing_files)"; then
  printf 'AGE_IDENTITY_PATH=%s\n' "$resolved"
  exit 0
fi

echo "::error ::Missing age identity (checked explicit path, runner home, managed host path, and injected secrets)" >&2
exit 1
