#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

PROJECT_ENV=""
COMPONENT=""
PACKAGE=""
EXPECTED_SHA=""
VERSION=""
HEALTH_URL=""
APPROVAL_FILE=""
APPLY=0
while [ "$#" -gt 0 ]; do
  case "$1" in
    --project-env) PROJECT_ENV="$2"; shift 2 ;;
    --component) COMPONENT="$2"; shift 2 ;;
    --package) PACKAGE="$2"; shift 2 ;;
    --sha256) EXPECTED_SHA="$2"; shift 2 ;;
    --version) VERSION="$2"; shift 2 ;;
    --health-url) HEALTH_URL="$2"; shift 2 ;;
    --approval-file) APPROVAL_FILE="$2"; shift 2 ;;
    --apply) APPLY=1; shift ;;
    *) die "unknown argument: $1" ;;
  esac
done

[ -n "$PROJECT_ENV" ] || die "--project-env is required"
load_env_file "$PROJECT_ENV"
assert_no_placeholders "$PROJECT_ENV"
require_file "$PACKAGE"
[[ "$EXPECTED_SHA" =~ ^[0-9a-f]{64}$ ]] || die "invalid sha256"
[[ "$VERSION" =~ ^[A-Za-z0-9._-]+$ ]] || die "invalid version"
verify_sha256 "$PACKAGE" "$EXPECTED_SHA"
python3 "$PACKAGE_ROOT/tools/validate_tar.py" "$PACKAGE"

SCAN_ROOT="$(mktemp -d)"
trap 'rm -rf "$SCAN_ROOT"' EXIT
tar -xzf "$PACKAGE" -C "$SCAN_ROOT"
PAYLOAD_ROOT="$SCAN_ROOT"
TOP_LEVEL_COUNT="$(find "$SCAN_ROOT" -mindepth 1 -maxdepth 1 -print | wc -l | tr -d ' ')"
if [ "$TOP_LEVEL_COUNT" = "1" ]; then
  ONLY_ENTRY="$(find "$SCAN_ROOT" -mindepth 1 -maxdepth 1 -print)"
  if [ -d "$ONLY_ENTRY" ]; then
    PAYLOAD_ROOT="$ONLY_ENTRY"
  fi
fi

case "$COMPONENT" in
  store) TARGET_ROOT="$STORE_ROOT"; PHP_BIN="${PHP73_BIN:-/usr/local/php/bin/php}" ;;
  ai-api) TARGET_ROOT="$AI_API_ROOT"; PHP_BIN="${PHP74_BIN:-/usr/local/php74/bin/php}" ;;
  ai-store) TARGET_ROOT="$AI_STORE_ROOT"; PHP_BIN="" ;;
  *) die "component must be store, ai-api, or ai-store" ;;
esac
validate_project_root "$TARGET_ROOT"

if ! python3 "$PACKAGE_ROOT/tools/scan_secrets.py" "$PAYLOAD_ROOT"; then
  die "secret-like material detected in code package"
fi

log "PLAN deploy component=$COMPONENT version=$VERSION target=$TARGET_ROOT"
log "PLAN backup current target, safe-extract release, merge files, syntax/HTTP check"
log "PLAN database migration and process restart are excluded"

[ "$APPLY" -eq 1 ] || {
  log "SHADOW_ONLY: code unchanged"
  exit 0
}

[ -n "$APPROVAL_FILE" ] || die "--approval-file is required with --apply"
require_apply_authorization "deploy-code-${COMPONENT}" "$APPROVAL_FILE" "$TARGET_HOST_REF"
require_cmd tar

RELEASE_ROOT="$(dirname "$TARGET_ROOT")/releases/$VERSION"
[ ! -e "$RELEASE_ROOT" ] || die "release already exists: $RELEASE_ROOT"
mkdir -p "$RELEASE_ROOT" "$BACKUP_ROOT/$PROJECT_CODE"

if [ -d "$TARGET_ROOT" ]; then
  BACKUP_FILE="$BACKUP_ROOT/$PROJECT_CODE/${COMPONENT}-before-${VERSION}-$(date '+%Y%m%dT%H%M%S%z').tar.gz"
  tar -czf "$BACKUP_FILE" -C "$(dirname "$TARGET_ROOT")" "$(basename "$TARGET_ROOT")"
  log "BACKUP_CREATED $BACKUP_FILE"
fi

cp -a "$PAYLOAD_ROOT"/. "$RELEASE_ROOT"/
mkdir -p "$TARGET_ROOT"
cp -a "$RELEASE_ROOT"/. "$TARGET_ROOT"/
chown -R www:www "$TARGET_ROOT"

if [ -n "$PHP_BIN" ] && [ -x "$PHP_BIN" ] && [ -f "$TARGET_ROOT/public/index.php" ]; then
  "$PHP_BIN" -l "$TARGET_ROOT/public/index.php"
fi
if [ -n "$HEALTH_URL" ]; then
  curl -fsS --connect-timeout 5 --max-time 15 "$HEALTH_URL" >/dev/null
fi
log "APPLICATION_DEPLOY_STEP_PASS component=$COMPONENT version=$VERSION"
