#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
STEP_ID='STEP_050M07R20QC_VM100_ALLOWED_SELECTOR_INTEGRATION'
TARGET_PACKAGE_SHA='04e93f483db6c99453056e650d600cc243f278b32543401419d7c6438b03f70f'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUNDLE_ROOT="${BUNDLE_ROOT:-$SCRIPT_DIR}"
export BUNDLE_ROOT
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
CONTRACT_ROOT="${ROUTER_CONTRACT_ROOT:-/opt/router-ops}"
WORKFLOW_LIB="${ROUTER_STEP_WORKFLOW_LIB:-$CONTRACT_ROOT/lib/router-step-workflow.sh}"
FINALIZER="${ROUTER_STEP_FINALIZE_BIN:-$CONTRACT_ROOT/bin/router-step-finalize}"
SAFE_PAYLOAD="${ROUTER_PUBLIC_SAFE_PAYLOAD_BIN:-$CONTRACT_ROOT/bin/router-public-safe-payload}"
POLICY_LIB="${ROUTER_PUBLICATION_POLICY_LIB:-$CONTRACT_ROOT/lib/router-publication-policy.sh}"
RUN_ID="$(date -u +%Y%m%d-%H%M%S)-$$"
RUN_DIR="${ROUTER_STEP_RUN_DIR:-$BASE/state/step-runs/$STEP_ID/$RUN_ID}"
CURRENT_FILE="$RUN_DIR/workflow-current.txt"
EVENTS_FILE="$RUN_DIR/workflow-events.tsv"
EVIDENCE_DIR="$RUN_DIR/evidence"
REPORT_DIR="$RUN_DIR/report"
PUBLIC_PAYLOAD="$RUN_DIR/public-payload"
FINAL_ENV="$RUN_DIR/finalize.txt"
LOCK_FILE="${ROUTER_STEP_LOCK_FILE:-$BASE/state/locks/${STEP_ID}.lock}"
CURRENT_PHASE=bootstrap
BACKUP_READY=false
CORE_CHANGE_COMPLETE=false
SOURCE_PUBLISHED=false
VM100_BACKUP_DIR=''
source "$WORKFLOW_LIB"
rollback_now() {
    [ "$BACKUP_READY" = true ] || return 0
    [ "$CORE_CHANGE_COMPLETE" = false ] || return 0
    export VM100_BACKUP_DIR
    "$BUNDLE_ROOT/rollback/rollback.sh"
}
publish_stop_report() {
    local phase="$1" line="$2" rc="$3"
    python3 "$BUNDLE_ROOT/scripts/build_stop_report.py" --step-id "$STEP_ID" --phase "$phase" --line "$line" --rc "$rc" --core-complete "$CORE_CHANGE_COMPLETE" --output "$REPORT_DIR" --release-info "$BUNDLE_ROOT/release-info.json" --installer-sha "$BUNDLE_ROOT/installer.sha256" --bundle-manifest "$BUNDLE_ROOT/manifest.sha256" || return 1
    cp "$BUNDLE_ROOT/install.sh" "$REPORT_DIR/executed-step.sh"
    for f in preflight.txt snapshot.txt backup.txt apply.txt postcheck.txt source-publish.txt project-source.txt rollback.txt; do [[ ! -f "$EVIDENCE_DIR/$f" ]] || cp "$EVIDENCE_DIR/$f" "$REPORT_DIR/$f"; done
    local args=("$REPORT_DIR/report.txt" report.txt "$REPORT_DIR/facts.json" facts.json "$REPORT_DIR/facts-public.html" facts-public.html "$REPORT_DIR/verify-public.html" verify-public.html "$REPORT_DIR/rollback-public.html" rollback-public.html "$REPORT_DIR/release-info.json" release-info.json "$REPORT_DIR/installer.sha256" installer.sha256 "$REPORT_DIR/bundle-manifest.sha256" bundle-manifest.sha256 "$REPORT_DIR/executed-step.sh" executed-step.sh)
    for f in preflight.txt snapshot.txt backup.txt apply.txt postcheck.txt source-publish.txt project-source.txt rollback.txt; do [[ ! -f "$REPORT_DIR/$f" ]] || args+=("$REPORT_DIR/$f" "$f"); done
    ROUTER_PUBLICATION_POLICY_LIB="$POLICY_LIB" "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}" || return 1
    "$FINALIZER" --label step050m07r20qc_vm100_allowed_selector_integration --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
}
stop() {
    local line="$1" rc="$2"
    trap - ERR
    set +e
    local phase="${CURRENT_PHASE:-unknown}"
    [[ ! -f "$CURRENT_FILE" ]] || router_step_phase_fail "$phase" "line=$line rc=$rc" >/dev/null 2>&1 || true
    rollback_now > "$EVIDENCE_DIR/rollback.txt" 2>&1 || true
    if [[ -f "$CURRENT_FILE" ]] && router_step_publication_is_verified; then
        echo RESULT=PASS_WORKFLOW_ALREADY_COMPLETE
        echo LATE_ERROR_AFTER_COMPLETE=true
        exit 0
    fi
    publish_stop_report "$phase" "$line" "$rc" || true
    [[ ! -f "$FINAL_ENV" ]] || cat "$FINAL_ENV"
    echo RESULT=STOP_R20QC_VM100_ALLOWED_SELECTOR_INTEGRATION
    echo "STOP_PHASE=$phase"
    echo "STOP_LINE=$line"
    echo "STOP_RC=$rc"
    echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"
    echo RUNTIME_IMPACT=none_or_rolled_back
    echo LIVE_USER_MOVE=false
    exit "$rc"
}
trap 'stop "$LINENO" "$?"' ERR
mkdir -p "$RUN_DIR" "$EVIDENCE_DIR" "$REPORT_DIR" "$PUBLIC_PAYLOAD" "$(dirname "$LOCK_FILE")"
exec 9>"$LOCK_FILE"
flock -n 9
router_step_workflow_init "$CURRENT_FILE" "$EVENTS_FILE" preflight snapshot backup apply postcheck source_publish project_source report_build
CURRENT_PHASE=preflight
router_step_phase_begin preflight
"$BUNDLE_ROOT/scripts/preflight.sh" "$EVIDENCE_DIR" | tee "$EVIDENCE_DIR/preflight-main.txt"
grep -Fqx RESULT=PASS_R20QC_PREFLIGHT "$EVIDENCE_DIR/preflight-main.txt"
router_step_phase_complete preflight published_baseline_and_runtime_normalization_need_verified
CURRENT_PHASE=snapshot
router_step_phase_begin snapshot
if [[ -n "${ROUTER_R20QC_SNAPSHOT_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_SNAPSHOT_FIXTURE"; else "$BUNDLE_ROOT/scripts/snapshot.sh"; fi | tee "$EVIDENCE_DIR/snapshot.txt"
grep -Fqx RESULT=PASS_R20QC_SNAPSHOT "$EVIDENCE_DIR/snapshot.txt"
router_step_phase_complete snapshot pre_core_snapshot_ready
CURRENT_PHASE=backup
router_step_phase_begin backup
if [[ -n "${ROUTER_R20QC_BACKUP_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_BACKUP_FIXTURE"; else "$BUNDLE_ROOT/scripts/backup-run.sh" "$RUN_ID"; fi | tee "$EVIDENCE_DIR/backup.txt"
grep -Fqx RESULT=PASS_R20QC_VM100_BACKUP "$EVIDENCE_DIR/backup.txt"
VM100_BACKUP_DIR="$(awk -F= '$1=="VM100_BACKUP_DIR"{print substr($0,index($0,"=")+1)}' "$EVIDENCE_DIR/backup.txt"|tail -1)"
[[ -n "$VM100_BACKUP_DIR" ]]
BACKUP_READY=true
router_step_phase_complete backup files_selector_nft_and_runtime_state_backup_ready
CURRENT_PHASE=apply
router_step_phase_begin apply
if [[ -n "${ROUTER_R20QC_APPLY_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_APPLY_FIXTURE"; else "$BUNDLE_ROOT/scripts/transfer-and-apply.sh" "$VM100_BACKUP_DIR"; fi | tee "$EVIDENCE_DIR/apply.txt"
grep -Fqx RESULT=PASS_R20QC_VM100_TARGET_APPLY "$EVIDENCE_DIR/apply.txt"
router_step_phase_complete apply allowed_selector_allocator_policy_installed
CURRENT_PHASE=postcheck
router_step_phase_begin postcheck
if [[ -n "${ROUTER_R20QC_POSTCHECK_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_POSTCHECK_FIXTURE"; else "$BUNDLE_ROOT/scripts/postcheck-run.sh" "$VM100_BACKUP_DIR"; fi | tee "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx RESULT=PASS_R20QC_VM100_POSTCHECK "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx LIVE_SELECTOR_MUTATION=false "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx SELECTOR_WRITE_DURING_STEP=false "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx NFT_SELECTOR_RUNTIME_MATCH_AFTER=true "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx ALLOWED_SELECTOR_INTEGRATION_PROVEN=true "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx EXHAUSTED_SELECTOR_RECONCILIATION_PROVEN=true "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx RECOVERY_GRADUAL_REBALANCE_PROVEN=true "$EVIDENCE_DIR/postcheck.txt"
CORE_CHANGE_COMPLETE=true
router_step_phase_complete postcheck allowed_exhausted_policy_and_runtime_selector_consistency_proven
CURRENT_PHASE=source_publish
router_step_phase_begin source_publish
if [[ -n "${ROUTER_R20QC_SOURCE_PUBLISH_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_SOURCE_PUBLISH_FIXTURE"; else "$BUNDLE_ROOT/scripts/source-publish.sh"; fi | tee "$EVIDENCE_DIR/source-publish.txt"
grep -Eq '^RESULT=PASS_ROUTER_MACHINE_CLOSE$|^RESULT=PASS_R20QC_SOURCE_PUBLISH_FIXTURE$' "$EVIDENCE_DIR/source-publish.txt"
grep -Eq '^GIT_FILE_COUNT=26$|^VM100_GIT_SOURCE_FILE_COUNT=26$' "$EVIDENCE_DIR/source-publish.txt"
SOURCE_PUBLISHED=true
router_step_phase_complete source_publish vm100_machine_git_committed_and_published
CURRENT_PHASE=project_source
router_step_phase_begin project_source
if [[ -n "${ROUTER_R20QC_PROJECT_SOURCE_FIXTURE:-}" ]]; then cat "$ROUTER_R20QC_PROJECT_SOURCE_FIXTURE"; else "$BUNDLE_ROOT/scripts/publish-project-source.sh" "$EVIDENCE_DIR/source-publish.txt" "$EVIDENCE_DIR/postcheck.txt" "$RUN_DIR/project-source"; fi | tee "$EVIDENCE_DIR/project-source.txt"
grep -Fqx RESULT=PASS_R20QC_PROJECT_SOURCE_PUBLISH "$EVIDENCE_DIR/project-source.txt"
router_step_phase_complete project_source canonical_project_source_post_published
CURRENT_PHASE=report_build
router_step_phase_begin report_build
python3 "$BUNDLE_ROOT/scripts/build_report.py" --preflight "$EVIDENCE_DIR/preflight-main.txt" --snapshot "$EVIDENCE_DIR/snapshot.txt" --backup "$EVIDENCE_DIR/backup.txt" --apply "$EVIDENCE_DIR/apply.txt" --postcheck "$EVIDENCE_DIR/postcheck.txt" --source-publish "$EVIDENCE_DIR/source-publish.txt" --project-source "$EVIDENCE_DIR/project-source.txt" --output "$REPORT_DIR" --release-info "$BUNDLE_ROOT/release-info.json" --installer-sha "$BUNDLE_ROOT/installer.sha256" --bundle-manifest "$BUNDLE_ROOT/manifest.sha256"
python3 -m json.tool "$REPORT_DIR/facts.json" >/dev/null
cp "$BUNDLE_ROOT/install.sh" "$REPORT_DIR/executed-step.sh"
for f in preflight-main.txt snapshot.txt backup.txt apply.txt postcheck.txt source-publish.txt project-source.txt; do cp "$EVIDENCE_DIR/$f" "$REPORT_DIR/${f/preflight-main/preflight}"; done
args=("$REPORT_DIR/report.txt" report.txt "$REPORT_DIR/facts.json" facts.json "$REPORT_DIR/facts-public.html" facts-public.html "$REPORT_DIR/verify-public.html" verify-public.html "$REPORT_DIR/rollback-public.html" rollback-public.html "$REPORT_DIR/release-info.json" release-info.json "$REPORT_DIR/installer.sha256" installer.sha256 "$REPORT_DIR/bundle-manifest.sha256" bundle-manifest.sha256 "$REPORT_DIR/executed-step.sh" executed-step.sh "$REPORT_DIR/preflight.txt" preflight.txt "$REPORT_DIR/snapshot.txt" snapshot.txt "$REPORT_DIR/backup.txt" backup.txt "$REPORT_DIR/apply.txt" apply.txt "$REPORT_DIR/postcheck.txt" postcheck.txt "$REPORT_DIR/source-publish.txt" source-publish.txt "$REPORT_DIR/project-source.txt" project-source.txt)
ROUTER_PUBLICATION_POLICY_LIB="$POLICY_LIB" "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}"
router_step_phase_complete report_build public_safe_payload_ready
CURRENT_PHASE=publication
"$FINALIZER" --label step050m07r20qc_vm100_allowed_selector_integration --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
router_step_workflow_mark_complete || true
cat "$FINAL_ENV"
STEP_REPORT_URL="$(awk -F= '$1=="PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$FINAL_ENV"|tail -1)"
set +e
TOKEN_FILE="$BASE/public/.router-public-token"
if [[ -f "$TOKEN_FILE" ]]; then TOKEN="$(cat "$TOKEN_FILE")"; LATEST="$BASE/public/r/$TOKEN/latest"; else LATEST=''; fi
latest_url() {
    local pattern="$1" name=''
    if [[ -n "$LATEST" && -d "$LATEST" ]]; then
        name="$(find "$LATEST" -mindepth 1 -maxdepth 1 -type d -name "$pattern" -printf '%T@ %f\n' 2>/dev/null | sort -n | tail -n 1 | cut -d' ' -f2-)"
        [[ -z "$name" ]] || printf 'https://reports.secret-studio.ru/latest/%s/\n' "$name"
    fi
}
LOCAL_M07_PLAN_URL="$(latest_url '*_local_architecture_plan_vm101_autonomous_hmn_recovery*')"
GLOBAL_PROJECT_PLAN_URL="$(latest_url '*_global_project_plan_wg_paid*')"
ACCESS_MAP_URL="$(latest_url '*_access_map_*')"
XS_MAP_URL="$(latest_url '*_xs_map_*')"
[[ -n "$XS_MAP_URL" ]] || XS_MAP_URL="$ACCESS_MAP_URL"
VM101_PUBLIC_URL="$(latest_url '*_vm101_git_source_*')"
VM121_PUBLIC_URL="$(latest_url '*_vm121_git_source_*')"
set -e
COMMIT="$(awk -F= '$1=="COMMIT" || $1=="VM100_GIT_SOURCE_COMMIT"{v=substr($0,index($0,"=")+1)} END{print v}' "$EVIDENCE_DIR/source-publish.txt")"
TREE="$(awk -F= '$1=="TREE" || $1=="VM100_GIT_SOURCE_TREE"{v=substr($0,index($0,"=")+1)} END{print v}' "$EVIDENCE_DIR/source-publish.txt")"
VM100_URL="$(awk -F= '$1=="VM100_PUBLIC_URL" || $1=="VM100_GIT_SOURCE_URL"{v=substr($0,index($0,"=")+1)} END{print v}' "$EVIDENCE_DIR/source-publish.txt")"
PROJECT_URL="$(awk -F= '$1=="PROJECT_SOURCE_POST_URL"{v=substr($0,index($0,"=")+1)} END{print v}' "$EVIDENCE_DIR/project-source.txt")"
NFT_NORMALIZED="$(awk -F= '$1=="NFT_NORMALIZATION_PERFORMED"{v=$2} END{print v}' "$EVIDENCE_DIR/postcheck.txt")"
echo RESULT=PASS_R20QC_VM100_ALLOWED_SELECTOR_INTEGRATION
echo "STEP_REPORT_URL=$STEP_REPORT_URL"
echo "PROJECT_SOURCE_POST_URL=$PROJECT_URL"
echo "LOCAL_M07_PLAN_URL=$LOCAL_M07_PLAN_URL"
echo "GLOBAL_PROJECT_PLAN_URL=$GLOBAL_PROJECT_PLAN_URL"
echo "ACCESS_MAP_URL=$ACCESS_MAP_URL"
echo "XS_MAP_URL=$XS_MAP_URL"
echo "VM100_PUBLIC_URL=$VM100_URL"
echo "VM101_PUBLIC_URL=$VM101_PUBLIC_URL"
echo "VM121_PUBLIC_URL=$VM121_PUBLIC_URL"
echo "VM100_GIT_COMMIT=$COMMIT"
echo "VM100_GIT_TREE=$TREE"
echo VM100_GIT_FILE_COUNT=26
echo RUNTIME_IMPACT=allowed_selector_policy_and_conditional_nft_normalization
echo LIVE_USER_MOVE=false
echo SELECTOR_WRITE_DURING_STEP=false
echo "NFT_NORMALIZATION_PERFORMED=${NFT_NORMALIZED:-unknown}"
echo "NFT_APPLY_DURING_STEP=${NFT_NORMALIZED:-unknown}"
echo NFT_SELECTOR_RUNTIME_MATCH_AFTER=true
echo AUTHORIZED_KEYS_MUTATED=false
echo SERVICE_RESTART_PERFORMED=false
echo ALLOWED_SELECTOR_INTEGRATION_PROVEN=true
echo EXHAUSTED_SELECTOR_RECONCILIATION_PROVEN=true
echo RECOVERY_GRADUAL_REBALANCE_PROVEN=true
echo NEXT_STEP=R20Q-D_VM101_ALWAYS_ON_FALLBACK_MAPPER
