#!/usr/bin/env bash
#
# Empacota o SDK para entregar ao proximo cliente.
#
#   ./sdk/empacotar.sh                 -> sdk/dist/contextia-sdk.tar.gz
#   ./sdk/empacotar.sh --zip           -> sdk/dist/contextia-sdk.zip
#
# O pacote e o que o cliente COPIA E COLA: descompacta na raiz do projeto dele e
# tem a skill em .claude/skills/ e as ferramentas em coleta/.
#
# A parte que importa deste script nao e o tar -- e a BARREIRA. O SDK sai da
# nossa maquina, onde ja houve mapeamento de cliente e chave de API embutida em
# codigo. Um pacote com o mapeamento do cliente anterior nao da erro: chega no
# proximo, parece exemplo, e vaza a estrutura de negocio de quem confiou na
# gente. Por isso ele se recusa a empacotar em vez de avisar.

set -euo pipefail

L_RAIZ="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
L_NOME="contextia-sdk"
L_DIST="$L_RAIZ/dist"
L_FORMATO="tar"

[ "${1:-}" = "--zip" ] && L_FORMATO="zip"

# ---------------------------------------------------------------- as barreiras
falhou=0
erro() { echo "  RECUSADO: $*" >&2; falhou=1; }

echo "Conferindo o que iria no pacote..."

# 1. Mapeamento ou adaptador de cliente. So o exemplo e o generic.py viajam.
while IFS= read -r f; do
  case "$(basename "$f")" in
    _exemplo-multiempresa.json) ;;
    *) erro "mapeamento de cliente em $f — mova para fora antes de empacotar" ;;
  esac
done < <(find "$L_RAIZ/coleta/mappings" -name '*.json' 2>/dev/null)

while IFS= read -r f; do
  case "$(basename "$f")" in
    generic.py) ;;
    *) erro "adaptador de cliente em $f — ele nao serve para o proximo" ;;
  esac
done < <(find "$L_RAIZ/coleta/sources" -name '*.py' 2>/dev/null)

# 2. Registro de onboarding. So o _TEMPLATE.md.
while IFS= read -r f; do
  case "$(basename "$f")" in
    _TEMPLATE.md) ;;
    *) erro "registro de cliente em $f — ele carrega as decisoes de outro" ;;
  esac
done < <(find "$L_RAIZ/.claude/docs" -name '*.md' 2>/dev/null)

# 3. Credencial. Uma chave ja viajou embutida em contextia_client.py uma vez.
#    `ctx_` seguido de hexadecimal longo e chave de verdade; `ctx_...` nao e.
if grep -rInE 'ctx_[0-9a-f]{16,}' "$L_RAIZ" --exclude-dir=dist --exclude=empacotar.sh >/dev/null 2>&1; then
  erro "chave de API embutida:"
  grep -rInE 'ctx_[0-9a-f]{16,}' "$L_RAIZ" --exclude-dir=dist --exclude=empacotar.sh \
    | sed -E 's/ctx_[0-9a-f]{16,}/ctx_<CHAVE>/g' >&2
fi

# 4. Arquivo de ambiente ou de chaves que tenha escorregado para dentro.
while IFS= read -r f; do
  erro "arquivo de segredo em $f"
done < <(find "$L_RAIZ" \( -name '.env*' -o -name '*.key' -o -name '*.keys' -o -name 'chaves*' \) -not -path '*/dist/*' 2>/dev/null)

# 5. Nada compila antes de sair.
for f in $(find "$L_RAIZ/coleta" -name '*.py'); do
  python3 -m py_compile "$f" 2>/dev/null || erro "erro de sintaxe em $f"
done

[ "$falhou" -eq 0 ] || { echo; echo "Nada foi empacotado."; exit 1; }

# ------------------------------------------------------------------ o pacote
rm -rf "$L_DIST/$L_NOME" "$L_DIST/$L_NOME.tar.gz" "$L_DIST/$L_NOME.zip"
mkdir -p "$L_DIST/$L_NOME"

# --dereference: a skill pode estar por link; o cliente precisa do arquivo.
tar -c --dereference \
    --exclude='__pycache__' --exclude='*.pyc' --exclude='dist' \
    --exclude='empacotar.sh' --exclude='sdk.tar' \
    -C "$L_RAIZ" . | tar -x -C "$L_DIST/$L_NOME"

if [ "$L_FORMATO" = "zip" ]; then
  ( cd "$L_DIST" && zip -qr "$L_NOME.zip" "$L_NOME" )
  L_SAIDA="$L_DIST/$L_NOME.zip"
else
  # --sort=name e --mtime: o mesmo conteudo gera o mesmo arquivo, entao da para
  # comparar dois pacotes por checksum e saber se mudou alguma coisa.
  tar -czf "$L_DIST/$L_NOME.tar.gz" \
      --sort=name --owner=0 --group=0 --numeric-owner \
      --mtime="@$(git -C "$L_RAIZ/.." log -1 --format=%ct 2>/dev/null || echo 0)" \
      -C "$L_DIST" "$L_NOME"
  L_SAIDA="$L_DIST/$L_NOME.tar.gz"
fi

rm -rf "$L_DIST/$L_NOME"

echo
echo "Pacote:  $L_SAIDA"
echo "Tamanho: $(du -h "$L_SAIDA" | cut -f1)"
echo "SHA-256: $(sha256sum "$L_SAIDA" | cut -d' ' -f1)"
echo
echo "No cliente:  tar -xzf $(basename "$L_SAIDA")  e a pasta $L_NOME/ esta pronta."
