#!/usr/bin/env bash
# =============================================================================
# deploy-identity-pkg.sh
#
# Publishes the IOTA Identity Move package to the IOTA testnet and
# automatically patches IOTA_IDENTITY_PKG_ID in .env.
#
# Prerequisites:
#   - IOTA CLI installed and on PATH
#   - Testnet wallet funded (iota client faucet)
#
# Usage:
#   ./scripts/deploy-identity-pkg.sh
# =============================================================================

set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

IOTA_NODE_URL="${IOTA_NODE_URL:-https://api.testnet.iota.cafe}"
IDENTITY_TAG="${IDENTITY_TAG:-v1.9.2-beta.1}"
CLONE_DIR="${TMPDIR:-/tmp}/iota-identity-pkg"

echo "==> Network:  testnet"
echo "==> Node URL: ${IOTA_NODE_URL}"
echo ""

# ---------------------------------------------------------------------------
# Check node reachability
# ---------------------------------------------------------------------------

echo "==> Checking IOTA node at ${IOTA_NODE_URL} ..."
if ! curl -sf "${IOTA_NODE_URL}" -X POST \
     -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","id":1,"method":"iota_getChainIdentifier","params":[]}' \
     > /dev/null; then
  echo "ERROR: IOTA node not reachable at ${IOTA_NODE_URL}."
  echo "       Check your internet connection or try again in a moment."
  exit 1
fi
echo "    OK — node is reachable."

# ---------------------------------------------------------------------------
# Check wallet balance
# ---------------------------------------------------------------------------

echo ""
echo "==> Checking wallet balance ..."
iota client switch --env testnet 2>/dev/null || true

if ! iota client gas --json 2>/dev/null | python3 -c "
import sys, json
data = json.load(sys.stdin)
if not data:
    sys.exit(1)
" 2>/dev/null; then
  echo "WARNING: Wallet may have insufficient gas."
  echo "         Run: iota client faucet"
fi

# ---------------------------------------------------------------------------
# Clone / update IOTA Identity repo
# ---------------------------------------------------------------------------

echo ""
echo "==> Cloning iotaledger/identity at tag ${IDENTITY_TAG} ..."
if [ -d "${CLONE_DIR}" ] && git -C "${CLONE_DIR}" rev-parse --git-dir >/dev/null 2>&1; then
  echo "    Using existing clone at ${CLONE_DIR}"
  cd "${CLONE_DIR}"
  git fetch --tags --quiet
  git checkout "tags/${IDENTITY_TAG}" --quiet
else
  rm -rf "${CLONE_DIR}"
  git clone --depth 1 --branch "${IDENTITY_TAG}" \
    https://github.com/iotaledger/identity.git \
    "${CLONE_DIR}"
  cd "${CLONE_DIR}"
fi

# ---------------------------------------------------------------------------
# Publish Move package
# ---------------------------------------------------------------------------

echo ""
echo "==> Publishing Move package to testnet ..."

PUBLISH_OUTPUT=$(iota client publish \
  --gas-budget 500000000 \
  --json \
  identity_iota_core/packages/iota_identity/) || true

echo "${PUBLISH_OUTPUT}"

PKG_ID=$(echo "${PUBLISH_OUTPUT}" | \
  python3 -c "
import sys, json, re

raw = sys.stdin.read()
pkg = ''

# Method 1: regex scan — works regardless of JSON structure or extra output
m = re.search(r'\"packageId\"\s*:\s*\"(0x[0-9a-fA-F]+)\"', raw)
if m:
    pkg = m.group(1)

# Method 2: try parsing JSON and look in objectChanges
if not pkg:
    # Find the outermost JSON object (skip non-JSON prefix/suffix)
    depth = 0
    start = -1
    end = -1
    for i, c in enumerate(raw):
        if c == '{':
            if depth == 0:
                start = i
            depth += 1
        elif c == '}':
            depth -= 1
            if depth == 0:
                end = i + 1
                break
    if start >= 0 and end > start:
        try:
            data = json.loads(raw[start:end])
            for obj in data.get('objectChanges', []):
                if obj.get('type') == 'published':
                    pkg = obj.get('packageId', '')
                    break
        except json.JSONDecodeError:
            pass

if pkg:
    print(pkg)
" 2>/dev/null || echo "")

# ANSI colors
BOLD='\033[1m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
WHITE='\033[1;37m'
DIM='\033[2m'
RED='\033[0;31m'
RESET='\033[0m'

W=70
line() {
    local text="$1"
    local visible
    visible=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g')
    local len=${#visible}
    local pad=$((W - len))
    if [ $pad -lt 0 ]; then pad=0; fi
    printf "${GREEN}║${RESET}%b%*s${GREEN}║${RESET}\n" "$text" "$pad" ""
}
TOP="${GREEN}╔$(printf '═%.0s' $(seq 1 $W))╗${RESET}"
MID="${GREEN}╠$(printf '═%.0s' $(seq 1 $W))╣${RESET}"
BOT="${GREEN}╚$(printf '═%.0s' $(seq 1 $W))╝${RESET}"

if [ -z "${PKG_ID}" ]; then
  echo ""
  echo -e "${YELLOW}Could not auto-detect packageId from the publish output.${RESET}"
  echo -e "  Look for ${BOLD}packageId${RESET} in the JSON above (starts with 0x...)."
  echo ""
  echo -ne "  ${CYAN}Paste the packageId here (or press ENTER to skip):${RESET} "
  read -r PKG_ID
  PKG_ID=$(echo "${PKG_ID}" | tr -d '[:space:]' | sed 's/^"//' | sed 's/"$//')
fi

if [ -z "${PKG_ID}" ]; then
  echo ""
  echo -e "  ${DIM}Skipped — set IOTA_IDENTITY_PKG_ID manually in .env later.${RESET}"
else
  # Auto-patch .env if it exists in the repo root.
  ENV_FILE="${REPO_ROOT}/.env"
  ENV_MSG="Copy the value above into your .env file."
  if [ -f "${ENV_FILE}" ]; then
    if sed --version 2>/dev/null | grep -q GNU; then
      sed -i "s|^IOTA_IDENTITY_PKG_ID=.*|IOTA_IDENTITY_PKG_ID=${PKG_ID}|" "${ENV_FILE}"
    else
      sed -i '' "s|^IOTA_IDENTITY_PKG_ID=.*|IOTA_IDENTITY_PKG_ID=${PKG_ID}|" "${ENV_FILE}"
    fi
    ENV_MSG=".env updated automatically"
  fi

  echo ""
  echo -e "$TOP"
  line ""
  line "  ${WHITE}${BOLD}Identity package deployed successfully${RESET}"
  line ""
  echo -e "$MID"
  line ""
  line "  ${BOLD}Package ID:${RESET}"
  line "  ${CYAN}${PKG_ID}${RESET}"
  line ""
  line "  Network: ${DIM}testnet (${IOTA_NODE_URL})${RESET}"
  line "  ${DIM}${ENV_MSG}${RESET}"
  line ""
  if [ -z "${WIZARD_MODE:-}" ]; then
    echo -e "$MID"
    line ""
    line "  ${BOLD}Next steps:${RESET}"
    line "    1. Start services:  ${DIM}docker compose up --build -d${RESET}"
    line "    2. Fund wallets:    ${DIM}./scripts/fund-services.sh${RESET}"
    line "    3. Onboard system:  ${DIM}see README step 7${RESET}"
    line ""
  fi
  echo -e "$BOT"
fi
