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

# Post or update an MR comment with analysis results
# Required env: GITLAB_TOKEN, CI_API_V4_URL, CI_PROJECT_ID,
#   CI_MERGE_REQUEST_IID, FALLOW_COMMAND
# Optional env: CHANGED_SINCE, INPUT_ROOT (for scoping results to changed files)

# Auth header
if [ -z "${GITLAB_TOKEN:-}" ]; then
  echo "WARNING: GITLAB_TOKEN is required to create or update MR comments; CI_JOB_TOKEN is read-only for MR notes in the official GitLab API. Skipping MR summary comment."
  exit 0
fi
: "${CI_API_V4_URL:?CI_API_V4_URL is required}"
: "${CI_PROJECT_ID:?CI_PROJECT_ID is required}"
: "${CI_MERGE_REQUEST_IID:?CI_MERGE_REQUEST_IID is required}"
AUTH_HEADER="PRIVATE-TOKEN: ${GITLAB_TOKEN}"

API_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=gitlab_common.sh
source "${SCRIPT_DIR}/gitlab_common.sh"

# Initialize two sidecar markers so downstream jobs always see definitive
# values. GitLab CI lacks an equivalent of $GITHUB_OUTPUT; these greppable
# text files serve the same role when added to `artifacts: paths:`.
# `fallow-skip-reason.txt` stays `none` here because comment.sh ALWAYS posts
# (even on dedup-lookup failure, where it may duplicate the summary note).
# `fallow-dedup-lookup-failed.txt` captures the degraded state without
# misleading consumers into thinking the post itself was skipped.
printf 'none\n' > fallow-skip-reason.txt
printf 'false\n' > fallow-dedup-lookup-failed.txt

render_with_fallow() {
  local format=$1
  local output=$2
  prepare_fallow_render_args "$format" || return 1
  case "${FALLOW_SUMMARY_SCOPE:-all}" in
    ""|all|diff)
      export FALLOW_SUMMARY_SCOPE="${FALLOW_SUMMARY_SCOPE:-all}"
      ;;
    *)
      echo "WARNING: Unsupported FALLOW_SUMMARY_SCOPE '${FALLOW_SUMMARY_SCOPE}', expected 'all' or 'diff'; using 'all'"
      export FALLOW_SUMMARY_SCOPE="all"
      ;;
  esac
  FALLOW_COMMENT_ID="${FALLOW_COMMENT_ID:-fallow-results}" fallow "${FALLOW_RENDER_ARGS[@]}" > "$output" 2> fallow-comment-stderr.log || true
  # Surface fallow's structured-error envelope before the marker check so the
  # CLI message lands in the GitLab job log rather than a generic warning.
  if jq -e '.error == true' "$output" > /dev/null 2>&1; then
    echo "WARNING: fallow render failed: $(jq -r '.message // "unknown error"' "$output")"
    return 1
  fi
  grep -q "^<!-- fallow-id: ${FALLOW_COMMENT_ID:-fallow-results} -->" "$output" \
    && grep -q "Generated by fallow\\." "$output"
}

if render_with_fallow pr-comment-gitlab fallow-mr-comment.md; then
  COMMENT_BODY=$(cat fallow-mr-comment.md)
  MARKER="<!-- fallow-id: ${FALLOW_COMMENT_ID:-fallow-results} -->"
  # Summary-only path: dedup-lookup failure means we cannot find an
  # existing MR comment. Post a fresh one anyway (duplicate is recoverable,
  # missing summary is silently broken). Warning + sidecar artifact still
  # surface the degradation for operators / downstream gates.
  _LOOKUP_TMP=$(mktemp); _LOOKUP_ERR=$(mktemp)
  _FALLOW_TMPS+=("$_LOOKUP_TMP" "$_LOOKUP_ERR")
  if curl_paginate --header "${AUTH_HEADER}" "${API_URL}?per_page=100" \
       > "$_LOOKUP_TMP" 2> "$_LOOKUP_ERR"; then
    EXISTING_NOTE_ID=$(MARKER="$MARKER" jq -r '.[] | select(.body | contains(env.MARKER)) | .id' "$_LOOKUP_TMP" \
      | head -1)
  else
    EXISTING_NOTE_ID=""
    _STDERR_HEAD=$(head -3 "$_LOOKUP_ERR" | tr '\n' ' ')
    echo "WARNING: fallow: failed to look up existing MR summary comment; posting a new one (may duplicate). stderr: ${_STDERR_HEAD} Re-run the job to retry. If persistent, verify GITLAB_TOKEN scopes (api, read_api)." >&2
    # Summary-only path: the post proceeds anyway, so do NOT flip
    # fallow-skip-reason.txt. Mark dedup-lookup-failed instead.
    printf 'true\n' > fallow-dedup-lookup-failed.txt
  fi

  if [ -n "$EXISTING_NOTE_ID" ]; then
    curl_retry \
      --header "${AUTH_HEADER}" \
      --header "Content-Type: application/json" \
      --request PUT \
      --data "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" \
      "${API_URL}/${EXISTING_NOTE_ID}" > /dev/null \
      && echo "Updated existing MR comment" \
      || echo "WARNING: Failed to update MR comment (check token permissions)"
  else
    curl_retry \
      --header "${AUTH_HEADER}" \
      --header "Content-Type: application/json" \
      --request POST \
      --data "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" \
      "${API_URL}" > /dev/null \
      && echo "Created new MR comment" \
      || echo "WARNING: Failed to create MR comment (check token permissions)"
  fi
  exit 0
fi

echo "WARNING: Failed to render typed MR comment"
exit 0
