#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Nexus first-time provisioning
# Run once on the server after: docker compose -f docker-compose.mirror.yml up -d
#
# Docker upstream:
#   By default → registry-1.docker.io  (Docker Hub directly — works from VPS)
#   With Liara  → docker-mirror.liara.ir  (Iranian relay, faster + more reliable)
#
#   To use Liara mirror, get credentials from https://app.liara.ir
#   (Account → Docker Mirror section), then run:
#     DOCKER_MIRROR_URL=https://docker-mirror.liara.ir \
#     DOCKER_MIRROR_USER=your-liara-email \
#     DOCKER_MIRROR_PASS=your-liara-token \
#     ./mirrors/nexus/provision.sh
#
# Usage:
#   ./mirrors/nexus/provision.sh                          # Docker Hub direct
#   NEXUS_ADMIN_PASS=MySecret ./mirrors/nexus/provision.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

NEXUS_URL="http://localhost:8081"
NEW_PASS="${NEXUS_ADMIN_PASS:-Mirror@2024!}"
CONTAINER="meezi-mirror-nexus"

# Docker upstream — override with Liara mirror once you have credentials
DOCKER_UPSTREAM="${DOCKER_MIRROR_URL:-https://registry-1.docker.io}"
DOCKER_USER="${DOCKER_MIRROR_USER:-}"
DOCKER_PASS="${DOCKER_MIRROR_PASS:-}"

# ── 1. Wait for Nexus ────────────────────────────────────────────────────────
echo "⏳  Waiting for Nexus (can take 2-3 min on first boot)..."
until curl -sf "$NEXUS_URL/service/rest/v1/status" | grep -q '"edition"'; do
  printf "."
  sleep 6
done
echo ""
echo "✅  Nexus is up"

# ── 2. Resolve admin password ────────────────────────────────────────────────
INIT_PASS_FILE=$(docker exec "$CONTAINER" sh -c 'cat /nexus-data/admin.password 2>/dev/null || true')

if [ -n "$INIT_PASS_FILE" ]; then
  echo "🔐  First-time password found — changing to configured password..."
  HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
    -u "admin:$INIT_PASS_FILE" -X PUT \
    "$NEXUS_URL/service/rest/v1/security/users/admin/change-password" \
    -H "Content-Type: text/plain" \
    -d "$NEW_PASS")
  if [ "$HTTP_CODE" = "204" ]; then
    echo "✅  Password updated"
  else
    echo "⚠️   Password change returned HTTP $HTTP_CODE — using original password"
    NEW_PASS="$INIT_PASS_FILE"
  fi
  ADMIN_PASS="$NEW_PASS"
else
  echo "ℹ️   admin.password not found — using NEXUS_ADMIN_PASS (already provisioned?)"
  ADMIN_PASS="$NEW_PASS"
fi

AUTH="-u admin:$ADMIN_PASS"

# ── 3. Enable anonymous read access ─────────────────────────────────────────
echo "🔓  Enabling anonymous access..."
curl -sf $AUTH -X PUT "$NEXUS_URL/service/rest/v1/security/anonymous" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true,"userId":"anonymous","realmName":"NexusAuthorizingRealm"}' \
  && echo "✅  Anonymous access enabled"

# Enable NuGet + npm token realms
curl -sf $AUTH -X PUT "$NEXUS_URL/service/rest/v1/security/realms/active" \
  -H "Content-Type: application/json" \
  -d '["NexusAuthenticatingRealm","NexusAuthorizingRealm","NuGetApiKey","NpmToken"]' \
  && echo "✅  Realms configured (NuGet, npm)"

# ── Helper: create or update repo ───────────────────────────────────────────
create_repo() {
  local TYPE="$1"
  local JSON="$2"
  local NAME
  NAME=$(echo "$JSON" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
  HTTP=$(curl -s -o /dev/null -w "%{http_code}" $AUTH \
    -X POST "$NEXUS_URL/service/rest/v1/repositories/$TYPE" \
    -H "Content-Type: application/json" \
    -d "$JSON")
  case "$HTTP" in
    201) echo "✅  $NAME created" ;;
    400) echo "⚠️   $NAME already exists (skipped — update via UI if needed)" ;;
    *)   echo "❌  $NAME failed — HTTP $HTTP" ;;
  esac
}

# ── 4. NuGet proxy ──────────────────────────────────────────────────────────
echo ""
echo "📦  Creating NuGet proxy → nuget.org ..."
create_repo "nuget/proxy" '{
  "name": "nuget-proxy",
  "online": true,
  "storage": {
    "blobStoreName": "default",
    "strictContentTypeValidation": true
  },
  "proxy": {
    "remoteUrl": "https://api.nuget.org/v3/index.json",
    "contentMaxAge": 1440,
    "metadataMaxAge": 1440
  },
  "negativeCache": { "enabled": true, "timeToLive": 1440 },
  "httpClient": { "blocked": false, "autoBlock": true }
}'

# ── 5. npm proxy ─────────────────────────────────────────────────────────────
echo "📦  Creating npm proxy → registry.npmjs.org ..."
create_repo "npm/proxy" '{
  "name": "npm-proxy",
  "online": true,
  "storage": {
    "blobStoreName": "default",
    "strictContentTypeValidation": false
  },
  "proxy": {
    "remoteUrl": "https://registry.npmjs.org",
    "contentMaxAge": 1440,
    "metadataMaxAge": 1440
  },
  "negativeCache": { "enabled": true, "timeToLive": 1440 },
  "httpClient": { "blocked": false, "autoBlock": true }
}'

# ── 6. Docker proxy ──────────────────────────────────────────────────────────
if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASS" ]; then
  echo "🐳  Creating Docker proxy → $DOCKER_UPSTREAM (with auth) ..."
  DOCKER_AUTH_JSON='"authentication":{"type":"username","username":"'"$DOCKER_USER"'","password":"'"$DOCKER_PASS"'"},'
  DOCKER_INDEX_TYPE="REGISTRY"   # Liara is a plain registry, not hub.docker.com
else
  echo "🐳  Creating Docker proxy → $DOCKER_UPSTREAM (no auth) ..."
  DOCKER_AUTH_JSON=""
  DOCKER_INDEX_TYPE="HUB"        # direct Docker Hub — use hub index
fi

create_repo "docker/proxy" '{
  "name": "docker-hub-proxy",
  "online": true,
  "storage": {
    "blobStoreName": "default",
    "strictContentTypeValidation": true
  },
  "proxy": {
    "remoteUrl": "'"$DOCKER_UPSTREAM"'",
    "contentMaxAge": 1440,
    "metadataMaxAge": 1440
  },
  "negativeCache": { "enabled": true, "timeToLive": 1440 },
  "httpClient": {
    "blocked": false,
    "autoBlock": true,
    '"$DOCKER_AUTH_JSON"'
    "connection": { "useTrustStore": false }
  },
  "docker": {
    "v1Enabled": false,
    "forceBasicAuth": false,
    "httpPort": 8083
  },
  "dockerProxy": {
    "indexType": "'"$DOCKER_INDEX_TYPE"'",
    "cacheForeignLayers": false
  }
}'

# ── Done ─────────────────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════════════════════════"
echo "🎉  Nexus provisioned!"
echo "═══════════════════════════════════════════════════════════════"
echo ""
echo "  UI     →  https://mirror.soroushasadi.com/"
echo "           admin / $ADMIN_PASS"
echo ""
echo "  NuGet  →  https://mirror.soroushasadi.com/repository/nuget-group/index.json"
echo "  npm    →  https://mirror.soroushasadi.com/repository/npm-group/"
echo "  Docker →  https://mirror.soroushasadi.com  ← upstream: $DOCKER_UPSTREAM"
echo ""
if [ -z "$DOCKER_USER" ]; then
  echo "  💡 To switch Docker upstream to Liara mirror (faster in Iran):"
  echo "     Get credentials from https://app.liara.ir → Docker Mirror, then:"
  echo ""
  echo "     DOCKER_MIRROR_URL=https://docker-mirror.liara.ir \\"
  echo "     DOCKER_MIRROR_USER=your-email \\"
  echo "     DOCKER_MIRROR_PASS=your-token \\"
  echo "     ./mirrors/nexus/update-docker-upstream.sh"
  echo ""
fi
echo "To activate Docker Hub mirror on this server:"
echo "  Merge docker/daemon-registry-mirror.example.json into /etc/docker/daemon.json"
echo '  { "registry-mirrors": ["https://mirror.soroushasadi.com"] }'
echo "  systemctl restart docker"
echo ""
