#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
VERIFY_ONLY=false
if [[ "${1:-}" == --verify-only ]]; then VERIFY_ONLY=true; shift; fi
[[ "$#" -ge 3 && "$#" -le 4 ]] || { echo 'Usage: router-step-bootstrap [--verify-only] ZIP ZIP_SHA256 INSTALLER_SHA256 [TARGET_PACKAGE_SHA256]' >&2; exit 2; }
ZIP="$1"; ZIP_SHA="$2"; INSTALL_SHA="$3"; TARGET_SHA="${4:-}"
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
GATE="${ROUTER_BUNDLE_GATE:-$BASE/bin/router-bundle-gate}"
STEP="$(basename "$ZIP" .zip)"
WORK="$(dirname "$ZIP")/.unpack-${STEP}-$$"
EMERGENCY_HANDLED=false

archive_current_latest() {
  if [[ -r "$BASE/lib/router-step-workflow.sh" ]]; then
    # shellcheck source=/dev/null
    source "$BASE/lib/router-step-workflow.sh"
    router_step_archive_latest_python "$BASE" /home/ops/incoming "$(date -u +%Y%m%d-%H%M%S)" 2>/dev/null || true
  fi
}

emergency_stop() {
  local rc="$1" line="$2" command="$3"
  trap - ERR
  [[ "$EMERGENCY_HANDLED" == false ]] || exit "$rc"
  EMERGENCY_HANDLED=true
  set +e
  echo RESULT=STOP_ROUTER_STEP_BOOTSTRAP
  echo "STEP=$STEP"
  echo "BOOTSTRAP_STOP_LINE=$line"
  echo "BOOTSTRAP_STOP_RC=$rc"
  printf 'BOOTSTRAP_STOP_COMMAND=%q\n' "$command"
  echo "RETAINED_UNPACK_DIR=$WORK"
  archive_current_latest
  exit "$rc"
}
trap 'rc=$?; emergency_stop "$rc" "$LINENO" "$BASH_COMMAND"' ERR

[[ -f "$ZIP" ]] || { echo RESULT=STOP_COPY_OR_TRANSFER_ERROR; echo COPY_VERIFY=FAIL; echo STEP_WAS_NOT_STARTED=true; exit 20; }
echo '>>> verify ZIP'
echo "$ZIP_SHA  $ZIP" | sha256sum -c -
rm -rf "$WORK"; mkdir -p "$WORK"
python3 - "$ZIP" "$WORK" "$STEP" <<'PYZIP'
import sys,zipfile
from pathlib import Path
z=Path(sys.argv[1]); d=Path(sys.argv[2]).resolve(); expected=sys.argv[3]
with zipfile.ZipFile(z) as f:
    roots=set()
    for m in f.infolist():
        n=m.filename.replace('\\','/'); parts=Path(n).parts
        if not parts: continue
        if any(c in n for c in ('\x00','\n','\r','\t')): raise SystemExit(f'unsafe ZIP member control character: {m.filename!r}')
        if n.startswith('/') or '..' in parts or ':' in parts[0]: raise SystemExit(f'unsafe ZIP member: {m.filename}')
        roots.add(parts[0]); target=(d/n).resolve()
        if target!=d and d not in target.parents: raise SystemExit(f'ZIP escape: {m.filename}')
    if roots!={expected}: raise SystemExit(f'unexpected ZIP roots: {sorted(roots)}')
    f.extractall(d)
PYZIP
DIR="$WORK/$STEP"
[[ -f "$DIR/install.sh" && -f "$DIR/manifest.sha256" && -f "$DIR/release-info.json" ]]
if find "$DIR" \( -type d -name __pycache__ -o -type f \( -name '*.pyc' -o -name '*.pyo' \) \) -print -quit | grep -q .; then
  echo RESULT=STOP_BUNDLE_PYTHON_BYTECODE_PRESENT; exit 22
fi
python3 - "$DIR" <<'PYCLASS' | while IFS=$'\t' read -r kind file; do
import sys
from pathlib import Path
root=Path(sys.argv[1])
for p in sorted(x for x in root.rglob('*') if x.is_file()):
    first=p.open('rb').readline(256).decode('ascii','ignore').rstrip('\r\n')
    kind={'#!/usr/bin/env bash':'bash','#!/bin/bash':'bash','#!/bin/sh':'sh','#!/bin/ash':'sh','#!/usr/bin/env python3':'python','#!/usr/bin/python3':'python'}.get(first)
    if kind: print(f'{kind}\t{p}')
PYCLASS
  case "$kind" in
    bash) chmod 700 "$file"; bash -n "$file" ;;
    sh) chmod 700 "$file"; sh -n "$file" ;;
    python) chmod 700 "$file"; python3 - "$file" <<'PYCHECK'
import sys
from pathlib import Path
p=Path(sys.argv[1]); compile(p.read_bytes(),str(p),'exec')
PYCHECK
      ;;
  esac
done
(cd "$DIR" && sha256sum -c manifest.sha256)
[[ "$(sha256sum "$DIR/install.sh"|awk '{print $1}')" == "$INSTALL_SHA" ]]
python3 - "$DIR/release-info.json" "$STEP" "$INSTALL_SHA" "$TARGET_SHA" <<'PYMETA'
import json,sys
p,step,ish,tsh=sys.argv[1:]
x=json.load(open(p,encoding='utf-8')); assert x['step_id']==step; assert x['expected_installer_sha256']==ish
if tsh: assert x.get('target_package_sha256')==tsh
PYMETA
BUNDLE_ROOT="$DIR" "$GATE" "$DIR"
echo MANIFEST_VERIFY=PASS
echo SYNTAX_VERIFY=PASS
echo FIXTURE_VERIFY=PASS
echo COPY_VERIFY=PASS
echo "STEP_SHA256=$INSTALL_SHA"
if [[ "$VERIFY_ONLY" == true ]]; then echo RESULT=PASS_ROUTER_STEP_BOOTSTRAP_VERIFY_ONLY; rm -rf "$WORK"; exit 0; fi
echo ">>> start $STEP"
set +e
BUNDLE_ZIP="$ZIP" EXPECTED_BUNDLE_SHA256="$ZIP_SHA" EXPECTED_INSTALLER_SHA256="$INSTALL_SHA" "$DIR/install.sh"
rc=$?
set -e
echo "BOOTSTRAP_INSTALLER_RC=$rc"
[[ "$rc" -eq 0 ]] && rm -rf "$WORK"
trap - ERR
exit "$rc"
