#!/bin/sh
set -eu
set -f

VERSION="1.0.0"
BASE_URL="https://sistema-citas-claude-code.vercel.app/downloads"
ARCHIVE="sistema-citas-v${VERSION}.zip"
CHECKSUM="${ARCHIVE}.sha256"
CURRENT_DIR=$(pwd)
TARGET_PARENT="${CURRENT_DIR}/sistema-citas-plugin-v${VERSION}"
TEMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/sistema-citas.XXXXXX")

cleanup() {
  rm -rf "${TEMP_DIR}"
}
trap cleanup EXIT INT TERM

if [ "${CURRENT_DIR}" = "/" ]; then
  echo "✗ Abre una carpeta de trabajo antes de instalar."
  exit 1
fi

if [ -e "${TARGET_PARENT}" ]; then
  echo "✗ Ya existe ${TARGET_PARENT}. No se sobrescribió nada."
  exit 1
fi

echo "1/3 Descargando archivos oficiales…"
curl --fail --location --max-redirs 3 --max-filesize 268435456 --proto '=https' --proto-redir '=https' --silent --show-error "${BASE_URL}/${ARCHIVE}" --output "${TEMP_DIR}/${ARCHIVE}"
curl --fail --location --max-redirs 3 --max-filesize 4096 --proto '=https' --proto-redir '=https' --silent --show-error "${BASE_URL}/${CHECKSUM}" --output "${TEMP_DIR}/${CHECKSUM}"
ARCHIVE_BYTES=$(wc -c < "${TEMP_DIR}/${ARCHIVE}" | tr -d ' ')
if [ "${ARCHIVE_BYTES}" -gt 268435456 ]; then
  echo "✗ El ZIP supera el tamaño permitido."
  exit 1
fi

echo "2/3 Verificando SHA-256…"
EXPECTED_HASH=$(awk -v archive="${ARCHIVE}" '$2 == archive { print $1 }' "${TEMP_DIR}/${CHECKSUM}")
ACTUAL_HASH=$(shasum -a 256 "${TEMP_DIR}/${ARCHIVE}" | awk '{ print $1 }')
if [ -z "${EXPECTED_HASH}" ] || [ "${EXPECTED_HASH}" != "${ACTUAL_HASH}" ]; then
  echo "✗ La huella del ZIP no coincide. Se canceló sin descomprimir."
  exit 1
fi

LISTING="${TEMP_DIR}/listing.txt"
unzip -Z1 "${TEMP_DIR}/${ARCHIVE}" > "${LISTING}"
ENTRY_COUNT=$(wc -l < "${LISTING}" | tr -d ' ')
if [ "${ENTRY_COUNT}" -lt 1 ] || [ "${ENTRY_COUNT}" -gt 3000 ]; then
  echo "✗ El ZIP contiene una cantidad de archivos no permitida."
  exit 1
fi
while IFS= read -r ENTRY; do
  case "${ENTRY}" in
    sistema-citas/*) ;;
    *) echo "✗ El ZIP contiene una ruta fuera de sistema-citas/."; exit 1 ;;
  esac
  ENTRY_WITHOUT_TRAILING_SLASH=${ENTRY%/}
  case "/${ENTRY_WITHOUT_TRAILING_SLASH}/" in
    *"/../"*|*"/./"*|*"//"*|*\\*)
      echo "✗ El ZIP contiene una ruta insegura."
      exit 1
      ;;
  esac
  PREVIOUS_IFS=${IFS}
  IFS='/'
  set -- ${ENTRY_WITHOUT_TRAILING_SLASH}
  IFS=${PREVIOUS_IFS}
  for SEGMENT do
    if ! printf '%s\n' "${SEGMENT}" | LC_ALL=C grep -Eq '^[][A-Za-z0-9._@+() -]+$'; then
      echo "✗ El ZIP contiene un nombre no portable."
      exit 1
    fi
    case "${SEGMENT}" in
      *[.\ ])
        echo "✗ El ZIP contiene un nombre ambiguo."
        exit 1
        ;;
    esac
    SEGMENT_STEM=${SEGMENT%%.*}
    SEGMENT_UPPER=$(printf '%s' "${SEGMENT_STEM}" | tr '[:lower:]' '[:upper:]')
    case "${SEGMENT_UPPER}" in
      CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])
        echo "✗ El ZIP contiene un nombre reservado."
        exit 1
        ;;
    esac
  done
done < "${LISTING}"
if [ "$(LC_ALL=C sort -f "${LISTING}" | uniq -i | wc -l | tr -d ' ')" != "${ENTRY_COUNT}" ]; then
  echo "✗ El ZIP contiene rutas duplicadas o ambiguas."
  exit 1
fi
if zipinfo -l "${TEMP_DIR}/${ARCHIVE}" | awk '$1 ~ /^[bclps]/ { found=1 } END { exit found ? 0 : 1 }'; then
  echo "✗ El ZIP contiene enlaces o archivos especiales."
  exit 1
fi
METADATA="${TEMP_DIR}/metadata.txt"
zipinfo -l "${TEMP_DIR}/${ARCHIVE}" > "${METADATA}"
if ! awk '
  $1 ~ /^-/ {
    expanded=$4 + 0
    compressed=$6 + 0
    total += expanded
    if (expanded > 268435456) unsafe=1
    if (expanded > 1048576 && (compressed == 0 || expanded > compressed * 200)) unsafe=1
  }
  END { if (total > 536870912 || unsafe) exit 1 }
' "${METADATA}"; then
  echo "✗ El ZIP se expande demasiado o tiene una compresión peligrosa."
  exit 1
fi
unzip -tq "${TEMP_DIR}/${ARCHIVE}" >/dev/null

echo "3/3 Descomprimiendo en una carpeta nueva…"
mkdir "${TARGET_PARENT}"
if ! unzip -q "${TEMP_DIR}/${ARCHIVE}" -d "${TARGET_PARENT}"; then
  rmdir "${TARGET_PARENT}" 2>/dev/null || true
  echo "✗ No fue posible descomprimir el plugin."
  exit 1
fi

echo "✓ Instalación preparada. Abre Claude Code con:"
echo "claude --plugin-dir \"${TARGET_PARENT}/sistema-citas\""
