#!/usr/bin/env bash

: <<'DOC'
API for getting and setting info in the project manifest.

Schema entries are either jq paths (start with . or [) or function names.
Function-valued entries are called to compute the value on first access.
DOC

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

__manifest_api_file="$PROJ/manifest.json"

declare -gA __manifest_api_cache
declare -gA __manifest_api_schema=(
  [command_name]='."command-name"'
  [description]=".description"
  [org]=".org"
  [repo]=".repo"
  [latest]=".latest"
  [stable]=".stable"
  [releases]=".releases"
  [major_name]='.naming.major'
  [minor_name]='.naming.minor'
  [patch_name]='.naming.patch'
  [godot_version]='.engines.godot.version'
  [godot_url]='.engines.godot.url'
  [godot_supported]='.engines.godot.supported | join(",")'
  [linear_team]='."linear-team"'
  [labels]='merged_labels'
)

: <<'DOC'
  Gets a particular key from the kaitos manifest.

  Usage: manifest_get <key>
DOC
function manifest_get() {
  local key="$1"
  local path="${__manifest_api_schema["$key"]}"

  if [[ -z "$path" ]]; then
    log "Unknown manifest.json key: '$key'"
    return 1
  fi

  if [[ -z "${__manifest_api_cache[$path]+isset}" ]]; then
    local value

    if [[ "$(type -t "$path" 2>/dev/null)" == "function" ]]; then
      if ! value=$("$path"); then
        log "Failed to compute manifest.json key '$key'"
        return 1
      fi
    else
      if ! value=$(jq -r "$path" < "$__manifest_api_file"); then
        log "Failed to read manifest.json key '$key'"
        return 1
      elif [[ "$value" == "null" ]]; then
        log "manifest.json key '$key' is null or missing"
        return 1
      fi
    fi

    __manifest_api_cache["$path"]="$value"
  fi

  echo "${__manifest_api_cache[$path]}"
}

: <<'DOC'
  Sets a particular key in the kaitos manifest.

  Usage: manifest_set <key> <value>
DOC
function manifest_set() {
  local key="$1"
  local value="$2"
  local path="${__manifest_api_schema["$key"]}"

  if [[ -z "$path" ]]; then
    log "Unknown manifest.json key: '$key'"
    return 1
  fi

  local temp_file
  temp_file="$(mktemp)"

  jq \
    --arg v "$value" \
    "$path = (\$v | tonumber? // \$v)" \
    "$__manifest_api_file" > "$temp_file"

  mv "$temp_file" "$__manifest_api_file"

  __manifest_api_cache["$path"]="$value"
}