#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUNDLE_ROOT="${BUNDLE_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
export BUNDLE_ROOT

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
WORKFLOW_LIB="${ROUTER_STEP_WORKFLOW_LIB:-$BASE/lib/router-step-workflow.sh}"
TRANSITION_LIB="${ROUTER_RUNTIME_TRANSITION_LIB:-$BASE/lib/router-runtime-transition.sh}"
FINALIZER="${ROUTER_STEP_FINALIZE_BIN:-$BASE/bin/router-step-finalize}"
SAFE_PAYLOAD="${ROUTER_PUBLIC_SAFE_PAYLOAD_BIN:-$BASE/bin/router-public-safe-payload}"
MACHINE_CLOSE="${ROUTER_MACHINE_CLOSE_SAFE:-$BASE/bin/router-machine-close-safe}"
RUN_TARGET="${ROUTER_P30H_RUN_TARGET:-$BUNDLE_ROOT/scripts/run-target.sh}"

release_env="$("$BASE/bin/router-release-contract" env --root "$BUNDLE_ROOT")"
eval "$release_env"
STEP_ID="$ROUTER_RELEASE_STEP_ID"
TARGET_PACKAGE_SHA256="$ROUTER_RELEASE_TARGET_PACKAGE_SHA256"
TARGET_PACKAGE="$BUNDLE_ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH"
EXPECTED_FINAL_TREE="$(cat "$BUNDLE_ROOT/reference/expected-final-tree.txt")"
EXPECTED_FINAL_COUNT="$(cat "$BUNDLE_ROOT/reference/expected-final-file-count.txt")"

RUN_ID="${ROUTER_P30H_RUN_ID:-$(date -u +%Y%m%d-%H%M%S)-$$}"
[[ "$RUN_ID" =~ ^[A-Za-z0-9-]+$ ]]
RUN_DIR="${ROUTER_STEP_RUN_DIR:-$BASE/state/step-runs/$STEP_ID/$RUN_ID}"
EVIDENCE_DIR="$RUN_DIR/evidence"
REPORT_DIR="$RUN_DIR/report"
PUBLIC_PAYLOAD="$RUN_DIR/public-payload"
CURRENT_FILE="$RUN_DIR/workflow-current.txt"
EVENTS_FILE="$RUN_DIR/workflow-events.tsv"
TRANSITION_FILE="$RUN_DIR/runtime-transition.txt"
FINAL_ENV="$RUN_DIR/finalize.txt"
LOCK_FILE="${ROUTER_STEP_LOCK_FILE:-$BASE/state/locks/${STEP_ID}.lock}"
CURRENT_PHASE=preflight
BACKUP_READY=false
CORE_CHANGE_COMPLETE=false
ROLLBACK_STATUS=not_required
LATEST_ARCHIVE=not_created

source "$WORKFLOW_LIB"
source "$TRANSITION_LIB"
mkdir -p "$RUN_DIR" "$EVIDENCE_DIR" "$REPORT_DIR" "$(dirname "$LOCK_FILE")"
exec 9>"$LOCK_FILE"
flock -n 9 || {
  echo RESULT=STOP_P30H_STEP_ALREADY_RUNNING
  echo STEP_WAS_NOT_STARTED=true
  exit 75
}

router_step_workflow_init "$CURRENT_FILE" "$EVENTS_FILE" \
  preflight backup apply postcheck source_publish report_build finalization latest
router_runtime_transition_init "$TRANSITION_FILE"
router_runtime_transition_set "$TRANSITION_FILE" TRANSFER_VERIFIED true

rollback_now() {
  [ "$BACKUP_READY" = true ] || return 0
  [ "$CORE_CHANGE_COMPLETE" = false ] || return 0
  router_runtime_transition_rollback_allowed "$TRANSITION_FILE" || return 0
  "$RUN_TARGET" rollback "$RUN_ID" "$TARGET_PACKAGE_SHA256" > "$EVIDENCE_DIR/rollback.txt" 2>&1 || return $?
  grep -Fqx RESULT=PASS_P30H_R01_ROLLBACK "$EVIDENCE_DIR/rollback.txt"
}

build_report() {
  python3 "$BUNDLE_ROOT/scripts/build-report.py" \
    --bundle "$BUNDLE_ROOT" \
    --run-dir "$RUN_DIR" \
    --result "$1" \
    --phase "$2" \
    --rc "$3" \
    --line "$4" \
    --core-complete "$CORE_CHANGE_COMPLETE" \
    --rollback-status "$ROLLBACK_STATUS"
}

publish_report() {
  local args=() file
  for file in report.txt facts.json facts-public.html verify-public.html rollback-public.html release-info.json installer.sha256 bundle-manifest.sha256 executed-step.sh executed-worker.sh workflow-current.txt workflow-events.tsv; do
    [[ ! -f "$REPORT_DIR/$file" ]] || args+=("$REPORT_DIR/$file" "$file")
  done
  for file in preflight backup apply postcheck source-publish rollback; do
    [[ ! -f "$REPORT_DIR/$file.txt" ]] || args+=("$REPORT_DIR/$file.txt" "$file.txt")
  done
  "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}"
  "$FINALIZER" \
    --label step_vm121_p30h_admin_invite_trial_r01 \
    --payload-dir "$PUBLIC_PAYLOAD" \
    --workflow-current "$CURRENT_FILE" \
    --workflow-events "$EVENTS_FILE" \
    --output-env "$FINAL_ENV" \
    --expect-kind step-report
}

archive_latest() {
  router_step_archive_latest_python "$BASE" "$INCOMING" "$(date -u +%Y%m%d-%H%M%S)" > "$EVIDENCE_DIR/latest.txt" 2>&1
  cat "$EVIDENCE_DIR/latest.txt"
  grep -Fqx RESULT=PASS_ROUTER_STEP_ARCHIVE_LATEST "$EVIDENCE_DIR/latest.txt"
  LATEST_ARCHIVE="$(awk -F= '$1=="LATEST_ARCHIVE" {print substr($0,index($0,"=")+1)}' "$EVIDENCE_DIR/latest.txt" | tail -n1)"
  [[ -n "$LATEST_ARCHIVE" ]]
}

stop() {
  local line="$1" rc="$2" command="$3" phase="$CURRENT_PHASE"
  trap - ERR HUP INT TERM
  set +e
  router_step_phase_fail "$phase" "line=$line rc=$rc" >/dev/null 2>&1
  if [[ "$BACKUP_READY" == true && "$CORE_CHANGE_COMPLETE" == false ]]; then
    if rollback_now; then
      ROLLBACK_STATUS=restored
    else
      ROLLBACK_STATUS=failed
    fi
  elif [[ "$CORE_CHANGE_COMPLETE" == true ]]; then
    ROLLBACK_STATUS=preserved_accepted_core
  fi
  if router_step_should_publish_stop; then
    if build_report STOP "$phase" "$rc" "$line"; then
      publish_report || echo STOP_REPORT_FINALIZATION=FAILED
    else
      echo STOP_REPORT_BUILD=FAILED
    fi
  fi
  archive_latest || {
    echo STOP_LATEST_ARCHIVE=FAILED
    cat "$EVIDENCE_DIR/latest.txt" 2>/dev/null
  }
  router_step_emit_stop_evidence \
    STOP_P30H_R01_VM121_ADMIN_INVITE_TRIAL \
    "$phase" "$line" "$rc" "$command" \
    VM121 "$CORE_CHANGE_COMPLETE" "$ROLLBACK_STATUS" "$LATEST_ARCHIVE" \
    inspect_run_evidence_and_continue_from_first_unfinished_phase
  [[ "$CORE_CHANGE_COMPLETE" != true ]] || echo CONTINUATION_REQUIRED=true
  exit "$rc"
}

trap 'stop "$LINENO" "$?" "$BASH_COMMAND"' ERR
trap 'stop "$LINENO" 129 "signal HUP"' HUP
trap 'stop "$LINENO" 130 "signal INT"' INT
trap 'stop "$LINENO" 143 "signal TERM"' TERM

run_target_phase() {
  local phase="$1" expected="$2"
  CURRENT_PHASE="$phase"
  router_step_phase_begin "$phase"
  "$RUN_TARGET" "$phase" "$RUN_ID" "$TARGET_PACKAGE_SHA256" > "$EVIDENCE_DIR/$phase.txt" 2>&1
  cat "$EVIDENCE_DIR/$phase.txt"
  grep -Fqx "RESULT=$expected" "$EVIDENCE_DIR/$phase.txt"
}

run_target_phase preflight PASS_P30H_R01_PREFLIGHT
router_runtime_transition_set "$TRANSITION_FILE" PREFLIGHT_COMPLETE true
router_step_phase_complete preflight exact_vm121_source_alembic_schema_and_candidate_verified

run_target_phase backup PASS_P30H_R01_BACKUP
BACKUP_READY=true
router_runtime_transition_set "$TRANSITION_FILE" BACKUP_READY true
router_step_phase_complete backup vm121_admin_invite_trial_source_and_backend_database_backed_up

CURRENT_PHASE=apply
router_step_phase_begin apply
"$BUNDLE_ROOT/scripts/vm121-apply.sh" "$TARGET_PACKAGE_SHA256" "$TARGET_PACKAGE" "$RUN_ID" > "$EVIDENCE_DIR/apply.txt" 2>&1
cat "$EVIDENCE_DIR/apply.txt"
for marker in \
  P30H_SOURCE_INSTALLED=PASS \
  P30H_ALEMBIC_UPGRADE=PASS \
  P30H_BACKEND_STABILITY=PASS \
  P30H_TARGET_SOURCE_HASH_MATCH=PASS \
  RESULT=PASS_P30H_R01_APPLY
do
  grep -Fqx "$marker" "$EVIDENCE_DIR/apply.txt"
done
router_runtime_transition_set "$TRANSITION_FILE" FILES_INSTALLED true
router_step_phase_complete apply admin_invite_trial_schema_and_backend_source_applied

run_target_phase postcheck PASS_P30H_R01_POSTCHECK
CORE_CHANGE_COMPLETE=true
router_runtime_transition_set "$TRANSITION_FILE" CORE_CHANGE_COMPLETE true
router_runtime_transition_set "$TRANSITION_FILE" ACTIVATION_COMPLETE true
router_step_phase_complete postcheck production_read_only_contract_and_rehearsed_admin_invite_trial_target_passed

CURRENT_PHASE=source_publish
router_step_phase_begin source_publish
"$MACHINE_CLOSE" vm121 \
  "$STEP_ID P30H admin invite trial override: ordinary Admin Commercial invite may set 1-30 trial days; omitted keeps offer default; user referral default and campaign trial authority preserved" \
  > "$EVIDENCE_DIR/source-publish.txt" 2>&1
cat "$EVIDENCE_DIR/source-publish.txt"
grep -Fqx RESULT=PASS_ROUTER_MACHINE_CLOSE "$EVIDENCE_DIR/source-publish.txt"
TREE="$(awk -F= '$1=="TREE" {print $2}' "$EVIDENCE_DIR/source-publish.txt" | tail -n1)"
COUNT="$(awk -F= '$1=="GIT_FILE_COUNT" {print $2}' "$EVIDENCE_DIR/source-publish.txt" | tail -n1)"
echo "EXPECTED_TARGET_TREE=$EXPECTED_FINAL_TREE"
echo "PUBLISHED_TARGET_TREE=$TREE"
echo "EXPECTED_TARGET_FILE_COUNT=$EXPECTED_FINAL_COUNT"
echo "PUBLISHED_TARGET_FILE_COUNT=$COUNT"
[[ "$TREE" == "$EXPECTED_FINAL_TREE" ]]
[[ "$COUNT" == "$EXPECTED_FINAL_COUNT" ]]
router_step_phase_complete source_publish vm121_machine_git_github_roundtrip_published_exact_target_tree

CURRENT_PHASE=report_build
router_step_phase_begin report_build
build_report PASS none 0 0
router_step_phase_complete report_build p30h_admin_invite_trial_evidence_ready

CURRENT_PHASE=finalization
router_step_phase_begin finalization
publish_report
router_step_phase_complete finalization canonical_report_http_verified

CURRENT_PHASE=latest
router_step_phase_begin latest
archive_latest
router_step_phase_complete latest fresh_latest_archive_verified
router_step_workflow_mark_complete
trap - ERR HUP INT TERM
cat "$FINAL_ENV"
echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
echo CORE_CHANGE_COMPLETE=true
echo ROLLBACK_STATUS=not_required
echo RESULT=PASS_P30H_R01_VM121_ADMIN_INVITE_TRIAL
