#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
BUNDLE_ROOT="${BUNDLE_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"; export BUNDLE_ROOT
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"; INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
source "$BASE/lib/router-step-workflow.sh"
source "$BASE/lib/router-runtime-transition.sh"
eval "$("$BASE/bin/router-release-contract" env --root "$BUNDLE_ROOT")"
STEP_ID="$ROUTER_RELEASE_STEP_ID"
RUN_ID="$(date -u +%Y%m%d-%H%M%S)-$$"
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"
CURRENT_PHASE=preflight; BACKUP_READY=false; CORE_CHANGE_COMPLETE=false; ROLLBACK_STATUS=not_required; LATEST_ARCHIVE=not_created; PUBLIC_LOCK_HELD=false
[[ "$(id -un)" == ops && "$(id -u)" == 1000 && "$(id -g)" == 1000 ]] || { echo STOP=B5C_R03_MUST_RUN_AS_OPS;exit 80; }
[[ "$BASE" == /opt/router-ops ]] || { echo STOP=B5C_R03_UNEXPECTED_BASE;exit 80; }
mkdir -p "$RUN_DIR" "$EVIDENCE_DIR" "$REPORT_DIR"
exec 9>"$BASE/state/locks/$STEP_ID.lock"; flock -n 9 || { echo RESULT=STOP_B5C_R03_ALREADY_RUNNING;exit 75; }
# Existing publisher lock; no new lock or transport. Release before invoking publisher.
exec 7<"$BASE/state/locks/public-publish.lock"; flock -n 7 || { echo RESULT=STOP_B5C_R03_PUBLISHER_BUSY;exit 75; }
PUBLIC_LOCK_HELD=true
router_step_workflow_init "$CURRENT_FILE" "$EVENTS_FILE" preflight backup apply postcheck source_publish report_build finalization latest
router_runtime_transition_init "$TRANSITION_FILE"
run_phase(){
 local p="$1"; CURRENT_PHASE="$p";router_step_phase_begin "$p"
 if [[ "$p" == apply ]];then "$BUNDLE_ROOT/scripts/owner-apply.sh" "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" "$RUN_DIR" >"$EVIDENCE_DIR/$p.txt" 2>&1
 else "$BUNDLE_ROOT/scripts/run-target.sh" "$p" "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" "$RUN_DIR" >"$EVIDENCE_DIR/$p.txt" 2>&1;fi
 cat "$EVIDENCE_DIR/$p.txt"
 grep -Fqx "RESULT=PASS_B5C_R03_${p^^}" "$EVIDENCE_DIR/$p.txt"
 router_step_phase_complete "$p" guarded_metadata_verified
}
rollback_now(){
 [ "$BACKUP_READY" = true ] || return 0
 [ "$CORE_CHANGE_COMPLETE" = false ] || return 0
 router_runtime_transition_rollback_allowed "$TRANSITION_FILE" || return 0
 "$BUNDLE_ROOT/scripts/run-target.sh" rollback "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" "$RUN_DIR" >"$EVIDENCE_DIR/rollback.txt" 2>&1 || return $?
 cat "$EVIDENCE_DIR/rollback.txt"
 grep -Fqx RESULT=PASS_B5C_R03_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
 "$BASE/bin/router-public-safe-payload" "$PUBLIC_PAYLOAD" "${args[@]}"
 "$BASE/bin/router-step-finalize" --label step_vm130_b5c_publication_ownership_close_r03 --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 -n 1)"; [[ -n "$LATEST_ARCHIVE" ]]
}
release_lock(){
 if [[ "$PUBLIC_LOCK_HELD" == true ]];then flock -u 7 || true;exec 7<&-;PUBLIC_LOCK_HELD=false;fi
}
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
 release_lock
 if [[ "$phase" == finalization ]];then echo 'NO_SECOND_STOP_REPORT=true'
 elif 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
 else echo NO_SECOND_STOP_REPORT=true;fi
 archive_latest || echo STOP_LATEST_ARCHIVE=FAILED
 router_step_emit_stop_evidence STOP_B5C_R03_VM130_PUBLICATION_OWNERSHIP_CLOSE "$phase" "$line" "$rc" "$command" VM130 "$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_phase preflight;router_runtime_transition_set "$TRANSITION_FILE" PREFLIGHT_COMPLETE true
run_phase backup;BACKUP_READY=true;router_runtime_transition_set "$TRANSITION_FILE" BACKUP_READY true
run_phase apply;router_runtime_transition_set "$TRANSITION_FILE" FILES_INSTALLED true
run_phase postcheck;CORE_CHANGE_COMPLETE=true;router_runtime_transition_set "$TRANSITION_FILE" CORE_CHANGE_COMPLETE true
release_lock
CURRENT_PHASE=source_publish;router_step_phase_begin source_publish
{ echo SOURCE_CONTENT_CHANGED=false;echo VM100_MACHINE_GIT_PUBLISH_INVOKED=false;echo RESULT=PASS_B5C_R03_SOURCE_UNCHANGED; } >"$EVIDENCE_DIR/source-publish.txt"
cat "$EVIDENCE_DIR/source-publish.txt"
router_step_phase_complete source_publish no_source_content_changed
CURRENT_PHASE=report_build;router_step_phase_begin report_build;build_report PASS none 0 0;router_step_phase_complete report_build sanitized_report_ready
CURRENT_PHASE=finalization;router_step_phase_begin finalization;publish_report;router_step_phase_complete finalization public_report_verified
CURRENT_PHASE=latest;router_step_phase_begin latest;archive_latest;router_step_phase_complete latest fresh_latest_archive_created
router_step_workflow_mark_complete
trap - ERR HUP INT TERM
cat "$FINAL_ENV";cat "$REPORT_DIR/report.txt"
echo RESULT=PASS_B5C_R03_VM130_PUBLICATION_OWNERSHIP_CLOSE
echo "RUN_DIR=$RUN_DIR"
echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
