#!/usr/bin/env bash
# Build versioned Linux + Windows zips for pos.siraya.food/downloads/printer/
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
POS_FRONTEND="$(cd "$ROOT/../siraya-pos/frontend" && pwd)"
OUT_DIR="${POS_FRONTEND}/public/downloads/printer"
MANIFEST_JSON="${POS_FRONTEND}/lib/marketing/printer-download-manifest.json"

VERSION="$(node -p "require('${ROOT}/package.json').version")"
LINUX_ZIP="SirayaPrinter-linux-x64-${VERSION}.zip"
WIN_ZIP="SirayaPrinter-windows-x64-${VERSION}.zip"

step() { echo "→ $*"; }

sha256_file() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | awk '{print $1}'
  else
    shasum -a 256 "$1" | awk '{print $1}'
  fi
}

human_size() {
  du -h "$1" | cut -f1
}

mkdir -p "$OUT_DIR"

step "Packaging Linux agent v${VERSION}…"
LINUX_SRC="${ROOT}/dist/agent-linux"
if [[ ! -f "${LINUX_SRC}/Install.sh" ]]; then
  step "Building Linux agent (dist/agent-linux)…"
  bash "${ROOT}/installer/linux/build-agent.sh" "$VERSION"
fi

rm -f "${OUT_DIR}/${LINUX_ZIP}"
(
  cd "$LINUX_SRC"
  zip -rq "${OUT_DIR}/${LINUX_ZIP}" . \
    -x "*.git*" \
    -x "service/payload/linux-x64/app/node_modules/**/test/*"
)

step "Staging Windows USB release v${VERSION}…"
WIN_SRC="${ROOT}/dist/release"
bash "${ROOT}/installer/linux/stage-windows-usb.sh" "$VERSION"
bash "${ROOT}/scripts/build-sync-exe.sh" || true
if [[ -f "${WIN_SRC}/Sync.exe" ]]; then
  : # already in release dir from build-sync-exe.sh
fi

step "Generating OTA sync manifest…"
node "${ROOT}/scripts/generate-sync-manifest.mjs"
node "${ROOT}/scripts/test-sync-manifest.mjs"

rm -f "${OUT_DIR}/${WIN_ZIP}"
(
  cd "$WIN_SRC"
  zip -rq "${OUT_DIR}/${WIN_ZIP}" \
    Install.cmd \
    Repair.cmd \
    Update.cmd \
    Open-Setup.cmd \
    STOP-AGENT.cmd \
    stop-agent.ps1 \
    start-agent.bat \
    Sync.exe \
    sync-apply.js \
    health-probe.js \
    install-service.js \
    uninstall-service.js \
    install-from-folder.ps1 \
    install-repair-cycle.ps1 \
    repair-from-folder.ps1 \
    manifest.json \
    START_HERE.txt \
    COPY_TO_WINDOWS.txt \
    payload/win-x64
)

step "Verifying Windows zip contents..."
WIN_ZIP_PATH="${OUT_DIR}/${WIN_ZIP}"
ZIP_LIST="$(unzip -Z1 "$WIN_ZIP_PATH")"
for entry in \
  "install-service.js" \
  "Install.cmd" \
  "start-agent.bat" \
  "install-from-folder.ps1" \
  "payload/win-x64/app/installer/windows/install-service.js" \
  "payload/win-x64/app/node_modules/node-windows/package.json"; do
  if ! grep -Fxq "$entry" <<< "$ZIP_LIST"; then
    echo "ERROR: ${WIN_ZIP} is missing required entry: ${entry}" >&2
    exit 1
  fi
done

if ! unzip -p "$WIN_ZIP_PATH" "payload/win-x64/app/index.js" | grep -q "manualSpoolerName"; then
  echo "ERROR: ${WIN_ZIP} index.js missing manual printer UI" >&2
  exit 1
fi

step "Writing manifest ${MANIFEST_JSON}…"
mkdir -p "$(dirname "$MANIFEST_JSON")"
node -e "
const fs = require('fs');
const path = require('path');
const version = '${VERSION}';
const outDir = '${OUT_DIR}';
const linuxZip = '${LINUX_ZIP}';
const winZip = '${WIN_ZIP}';
const linuxPath = path.join(outDir, linuxZip);
const winPath = path.join(outDir, winZip);
const sha = (p) => {
  const { execSync } = require('child_process');
  try {
    return execSync('sha256sum \"' + p + '\"', { encoding: 'utf8' }).split(/\s+/)[0];
  } catch {
    return execSync('shasum -a 256 \"' + p + '\"', { encoding: 'utf8' }).split(/\s+/)[0];
  }
};
const manifest = {
  version,
  releasedAt: new Date().toISOString(),
  productName: 'Siraya Receipt Printer',
  tagline: 'One-click thermal receipt printing for Siraya POS',
  uiUrl: 'http://127.0.0.1:5000',
  designerUrl: 'http://127.0.0.1:5000/designer',
  downloads: {
    linux: {
      file: linuxZip,
      href: '/downloads/printer/' + linuxZip,
      sizeBytes: fs.statSync(linuxPath).size,
      sizeLabel: require('child_process').execSync('du -h \"' + linuxPath + '\" | cut -f1', { encoding: 'utf8' }).trim(),
      sha256: sha(linuxPath),
      entry: 'Install.sh',
      requirements: 'Ubuntu 22.04+ or Debian 12+ (64-bit), USB thermal printer',
    },
    windows: {
      file: winZip,
      href: '/downloads/printer/' + winZip,
      sizeBytes: fs.statSync(winPath).size,
      sizeLabel: require('child_process').execSync('du -h \"' + winPath + '\" | cut -f1', { encoding: 'utf8' }).trim(),
      sha256: sha(winPath),
      entry: 'Install.cmd',
      requirements: 'Windows 10/11 (64-bit), USB thermal printer',
    },
  },
};
fs.writeFileSync('${MANIFEST_JSON}', JSON.stringify(manifest, null, 2) + '\n');
"

step "Cleaning older zip versions…"
find "$OUT_DIR" -maxdepth 1 -name 'SirayaPrinter-*.zip' ! -name "$LINUX_ZIP" ! -name "$WIN_ZIP" -delete 2>/dev/null || true

step "Building Windows SSH setup zip…"
mkdir -p "${POS_FRONTEND}/public/downloads/printer/tools"
bash "${ROOT}/../siraya-pos/deploy/build-windows-setup-zip.sh"

echo ""
echo "Done — Siraya Printer v${VERSION}"
echo "  Linux:   ${OUT_DIR}/${LINUX_ZIP} ($(human_size "${OUT_DIR}/${LINUX_ZIP}"))"
echo "  Windows: ${OUT_DIR}/${WIN_ZIP} ($(human_size "${OUT_DIR}/${WIN_ZIP}"))"
echo "  Page:    /downloads/printer/"
echo ""
echo "Deploy: cd siraya-pos && npm run deploy:frontend"
