#!/usr/bin/env bash
# jira-epic-link.sh  -  which fields link a new story to an existing epic.
#
# Jira links a story to its epic in two different ways. Cloud uses the standard
# `parent` field; Server and Data Center use an "Epic Link" custom field whose id
# differs per site. The id is discovered from the field list by its schema type,
# never assumed. When no way is found the story is created without a link and a
# warning says so, rather than writing a guessed field.
#
# Pure: the caller fetches /rest/api/2/serverInfo and /rest/api/2/field and
# passes the JSON in, so the decision is testable offline.
#
#   epic_link_fields <mode> <epicKey> <fieldId> <serverInfoJson> <fieldsJson>
#     mode: auto | parent | epicLinkField | none
#   Prints a JSON object to merge into the create body's `fields`.

EPIC_LINK_SCHEMA="com.pyxis.greenhopper.jira:gh-epic-link"

epic_link_fields() {
  local mode="${1:-auto}" epic="$2" field_id="$3" server="$4" fields="$5" deployment found
  command -v jq >/dev/null 2>&1 || { echo "ERR: jq is required to link an epic" >&2; return 3; }
  if [ -z "$epic" ] || [ "$mode" = "none" ]; then
    printf '{}\n'
    return 0
  fi
  case "$mode" in
    parent)
      jq -cn --arg e "$epic" '{parent: {key: $e}}'
      return 0
      ;;
    epicLinkField)
      if [ -z "$field_id" ]; then
        echo "WARN: epicLinkField mode needs issueTree.epicLinkFieldId; the epic is not linked" >&2
        printf '{}\n'
        return 0
      fi
      jq -cn --arg f "$field_id" --arg e "$epic" '{($f): $e}'
      return 0
      ;;
  esac
  deployment="$(printf '%s' "$server" | jq -r '.deploymentType // empty' 2>/dev/null || true)"
  if [ "$deployment" = "Cloud" ]; then
    jq -cn --arg e "$epic" '{parent: {key: $e}}'
    return 0
  fi
  found="${field_id:-$(printf '%s' "$fields" | jq -r --arg s "$EPIC_LINK_SCHEMA" \
    '[.[]? | select(.schema.custom == $s) | .id] | first // empty' 2>/dev/null || true)}"
  if [ -z "$found" ]; then
    echo "WARN: no epic-link field on this site; the stories are created without an epic" >&2
    printf '{}\n'
    return 0
  fi
  jq -cn --arg f "$found" --arg e "$epic" '{($f): $e}'
}
