#!/usr/bin/env bash
# ============================================================================
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Automation.CI
# INGROUP: moko-platform.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /automation/ci-issue-reporter.sh
# VERSION: 09.23.00
# BRIEF: Creates or updates a Gitea issue when a CI gate fails.
#        Deduplicates by searching open issues with the "ci-auto" label
#        whose title matches the gate. If a matching issue exists, a comment
#        is appended instead of opening a duplicate.
# ============================================================================

set -euo pipefail

# ── Defaults ────────────────────────────────────────────────────────────────
GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}"
GITEA_TOKEN="${GITEA_TOKEN:-}"
REPO="${GITHUB_REPOSITORY:-}"
RUN_URL="${GITHUB_SERVER_URL:-${GITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
LABEL_NAME="ci-auto"
LABEL_COLOR="#e11d48"

GATE=""
DETAILS=""
SEVERITY="error"
WORKFLOW=""

# ── Parse arguments ─────────────────────────────────────────────────────────
usage() {
  cat <<EOF
Usage: ci-issue-reporter.sh --gate NAME --details TEXT [OPTIONS]

Required:
  --gate      CI gate name (e.g. "Code Quality", "Self-Health")
  --details   Human-readable failure description

Optional:
  --severity  "error" (default) or "warning"
  --workflow  Workflow name for the issue title
  --repo      owner/repo (default: \$GITHUB_REPOSITORY)
  --run-url   URL to the CI run (auto-detected from env)
  --token     Gitea API token (default: \$GITEA_TOKEN)
  --url       Gitea base URL (default: \$GITEA_URL)
EOF
  exit 1
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --gate)     GATE="$2";       shift 2 ;;
    --details)  DETAILS="$2";    shift 2 ;;
    --severity) SEVERITY="$2";   shift 2 ;;
    --workflow) WORKFLOW="$2";   shift 2 ;;
    --repo)     REPO="$2";      shift 2 ;;
    --run-url)  RUN_URL="$2";   shift 2 ;;
    --token)    GITEA_TOKEN="$2"; shift 2 ;;
    --url)      GITEA_URL="$2"; shift 2 ;;
    -h|--help)  usage ;;
    *)          echo "Unknown option: $1"; usage ;;
  esac
done

[[ -z "$GATE" ]]         && { echo "ERROR: --gate is required"; usage; }
[[ -z "$DETAILS" ]]      && { echo "ERROR: --details is required"; usage; }
[[ -z "$GITEA_TOKEN" ]]  && { echo "ERROR: GITEA_TOKEN not set"; exit 1; }
[[ -z "$REPO" ]]         && { echo "ERROR: GITHUB_REPOSITORY not set"; exit 1; }

API="${GITEA_URL}/api/v1/repos/${REPO}"

# ── Build title ─────────────────────────────────────────────────────────────
if [[ -n "$WORKFLOW" ]]; then
  TITLE="[CI] ${WORKFLOW}: ${GATE} failed"
else
  TITLE="[CI] ${GATE} failed"
fi

# ── Ensure label exists ─────────────────────────────────────────────────────
ensure_label() {
  local exists
  exists=$(curl -sf -o /dev/null -w '%{http_code}' \
    -H "Authorization: token ${GITEA_TOKEN}" \
    "${API}/labels" 2>/dev/null || echo "000")

  if [[ "$exists" == "200" ]]; then
    # Check if label already exists
    local found
    found=$(curl -sf \
      -H "Authorization: token ${GITEA_TOKEN}" \
      "${API}/labels" 2>/dev/null \
      | grep -o "\"name\":\"${LABEL_NAME}\"" || true)

    if [[ -z "$found" ]]; then
      curl -sf -X POST \
        -H "Authorization: token ${GITEA_TOKEN}" \
        -H "Content-Type: application/json" \
        "${API}/labels" \
        -d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \
        > /dev/null 2>&1 || true
    fi
  fi
}

# ── Search for existing open issue ──────────────────────────────────────────
find_existing_issue() {
  # URL-encode the gate name for the query
  local query
  query=$(printf '%s' "[CI] ${GATE}" | sed 's/ /%20/g; s/\[/%5B/g; s/\]/%5D/g')

  local response
  response=$(curl -sf \
    -H "Authorization: token ${GITEA_TOKEN}" \
    "${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \
    2>/dev/null || echo "[]")

  # Extract the first matching issue number
  echo "$response" \
    | grep -oP '"number":\s*\K[0-9]+' \
    | head -1
}

# ── Build issue body ────────────────────────────────────────────────────────
build_body() {
  local severity_badge
  if [[ "$SEVERITY" == "error" ]]; then
    severity_badge="**Severity:** Error"
  else
    severity_badge="**Severity:** Warning"
  fi

  cat <<BODY
## CI Gate Failure: ${GATE}

${severity_badge}
**Workflow:** ${WORKFLOW:-unknown}
**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})

### Details

${DETAILS}

### Resolution

Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually.

---
*Auto-created by [ci-issue-reporter](${GITEA_URL}/${REPO}/src/branch/main/automation/ci-issue-reporter.sh)*
BODY
}

# ── Build comment body (for existing issues) ────────────────────────────────
build_comment() {
  cat <<COMMENT
### CI failure recurrence

**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})

${DETAILS}
COMMENT
}

# ── Main ────────────────────────────────────────────────────────────────────
ensure_label

EXISTING=$(find_existing_issue)

if [[ -n "$EXISTING" ]]; then
  # Append comment to existing issue
  COMMENT_BODY=$(build_comment)
  COMMENT_JSON=$(printf '%s' "$COMMENT_BODY" | python3 -c "
import sys, json
print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null)

  HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
    -H "Authorization: token ${GITEA_TOKEN}" \
    -H "Content-Type: application/json" \
    "${API}/issues/${EXISTING}/comments" \
    -d "${COMMENT_JSON}" 2>/dev/null || echo "000")

  if [[ "$HTTP" == "201" ]]; then
    echo "Commented on existing issue #${EXISTING}"
  else
    echo "WARNING: Failed to comment on issue #${EXISTING} (HTTP ${HTTP})"
  fi
else
  # Create new issue
  ISSUE_BODY=$(build_body)
  ISSUE_JSON=$(python3 -c "
import sys, json
body = sys.stdin.read()
print(json.dumps({
    'title': sys.argv[1],
    'body': body,
    'labels': []
}))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null)

  # Create the issue
  RESPONSE=$(curl -sf -X POST \
    -H "Authorization: token ${GITEA_TOKEN}" \
    -H "Content-Type: application/json" \
    "${API}/issues" \
    -d "${ISSUE_JSON}" 2>/dev/null || echo "{}")

  ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1)

  if [[ -n "$ISSUE_NUM" ]]; then
    # Apply label (separate call — more reliable across Gitea versions)
    LABEL_ID=$(curl -sf \
      -H "Authorization: token ${GITEA_TOKEN}" \
      "${API}/labels" 2>/dev/null \
      | grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \
      | head -1 || true)

    if [[ -n "$LABEL_ID" ]]; then
      curl -sf -X POST \
        -H "Authorization: token ${GITEA_TOKEN}" \
        -H "Content-Type: application/json" \
        "${API}/issues/${ISSUE_NUM}/labels" \
        -d "{\"labels\":[${LABEL_ID}]}" \
        > /dev/null 2>&1 || true
    fi

    echo "Created issue #${ISSUE_NUM}: ${TITLE}"
  else
    echo "WARNING: Failed to create issue"
    echo "Response: ${RESPONSE}"
  fi
fi
