#!/usr/bin/env bash
set -euo pipefail
source "$SHELLOPS_DIR/.envrc"

: <<'DOC'
Validates pull request metadata in CI environments.

Checks that the PR has a description, at least one label, and an assignee.
Fetches PR metadata from the Forgejo API using CI environment variables.
DOC

import "$SHELLOPS_DIR/lib/forgejo.api.sh"

USAGE="$(cat <<EOF
Validates pull request hygiene in CI.

Usage: ops pr-hygiene [-h,--help]

Checks:
  - PR has a description (body)
  - PR has at least one label
  - PR has an assignee

Environment:
  CI_COMMIT_PULL_REQUEST          Pull request number
  CI_COMMIT_PULL_REQUEST_LABELS   Comma-separated label names

  These are auto-detected from GitHub Actions event context if not
  already set. Owner and repo are read from manifest.json.

EOF
)"

function main() {
  parse_args "$@"
  validate_env

  local pr_json
  pr_json="$(fetch_pr)"

  local failed=0

  check_description "$pr_json" || failed=1
  check_labels                 || failed=1
  check_assignees "$pr_json"   || failed=1

  if [[ "$failed" -eq 1 ]]; then
    log ""
    log "Please add a description, at least one label, and an assignee to the PR."
    exit 1
  fi

  log "PASS: pr-hygiene"
}

function fetch_pr() {
  local options
  options="$(jq_set "{}" '.pr_number' "$CI_COMMIT_PULL_REQUEST")"
  options="$(jq_set "$options" '.token' "${FORGEJO_PR_TOKEN:-}")"
  get_pull_request "$options"
}

function validate_env() {
  if [[ -z "${CI_COMMIT_PULL_REQUEST:-}" ]]; then
    try_auto_detect_pr_env
  fi

  if [[ -z "${CI_COMMIT_PULL_REQUEST:-}" ]]; then
    error "CI_COMMIT_PULL_REQUEST is not set. Is this running in a PR pipeline?"
    exit 1
  fi
}

function try_auto_detect_pr_env() {
  if [[ -z "${GITHUB_ACTIONS:-}" || -z "${GITHUB_EVENT_PATH:-}" ]]; then
    return
  fi

  log "Auto-detecting PR environment from GitHub Actions context..."
  CI_COMMIT_PULL_REQUEST="$(jq -r '.pull_request.number' "$GITHUB_EVENT_PATH")"
  CI_COMMIT_PULL_REQUEST_LABELS="$(jq -r '[.pull_request.labels[].name] | join(",")' "$GITHUB_EVENT_PATH")"
  export CI_COMMIT_PULL_REQUEST CI_COMMIT_PULL_REQUEST_LABELS
}

function check_description() {
  local pr_json="$1"
  local body
  body="$(jq_get "$pr_json" '.body')"

  if [[ -z "$body" ]]; then
    log "FAIL: PR has no description"
    return 1
  fi
}

function check_labels() {
  local labels="${CI_COMMIT_PULL_REQUEST_LABELS:-}"

  if [[ -z "$labels" ]]; then
    log "FAIL: PR has no labels"
    return 1
  fi
}

function check_assignees() {
  local pr_json="$1"
  local count
  count="$(jq '.assignees | length' <<< "$pr_json")"

  if [[ "$count" -eq 0 ]]; then
    log "FAIL: PR has no assignee"
    return 1
  fi
}

function parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -h|--help) log "$USAGE" && exit 0 ;;
      -*)
        log "Unknown option: $1"
        log "$USAGE"
        exit 1
        ;;
    esac
    shift
  done
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  main "$@"
fi
