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

[ "$(id -un)" = "ops" ] || {
  echo "STOP: запускать на router-ops пользователем ops"
  exit 1
}

STEP="STEP_050M07R05B_AUDIT_AND_RESET_WORKFLOW"

TOKEN="e94a0859747d7b96f29c7fdafc2d0351ba603bb0a7e9e5a4"
ROOT="/opt/router-ops"
STATE_ROOT="$ROOT/state"
PUBROOT="$ROOT/public/r/$TOKEN"
PUBLIC_BASE="https://helena-background-beam-harry.trycloudflare.com/r/$TOKEN"

CANONICAL_STATE="$STATE_ROOT/current-vm101-canonical.env"
CANONICAL_CURRENT="$PUBROOT/vm101-canonical/current"

FAILED_FACTS="$PUBROOT/20260712-092211_step050m07r05_generate_complete_canonical_candidates/facts.json"
TRACEBACK_JSON="$PUBROOT/20260712-092504_step050m07r05a_capture_generator_traceback/traceback-summary.json"

TS="$(date -u +%Y%m%d-%H%M%S)"
REPORT_SLUG="${TS}_step050m07r05b_audit_and_reset_workflow"
REPORT_DIR="$PUBROOT/$REPORT_SLUG"

TRYCF_REPORT="$PUBLIC_BASE/$REPORT_SLUG/"
REPORT_TXT="${TRYCF_REPORT}report.txt"
FACTS_JSON="${TRYCF_REPORT}facts.json"

VM101_REFERENCE="$PUBLIC_BASE/vm101-reference/current/"
VM101_CANONICAL="$PUBLIC_BASE/vm101-canonical/current/"

WORKFLOW_ROOT="$STATE_ROOT/m07-workflow"
AUDIT_PRIVATE="$WORKFLOW_ROOT/audits/$TS"
QUARANTINE_ROOT="$STATE_ROOT/canonical/vm101/quarantine"

mkdir -p \
  "$REPORT_DIR" \
  "$AUDIT_PRIVATE" \
  "$QUARANTINE_ROOT"

cp -a "$0" "$REPORT_DIR/step.sh"
chmod 600 "$REPORT_DIR/step.sh"

state_value() {
  sed -n "s/^${1}=//p" "$CANONICAL_STATE" |
    tail -n1
}

json_value() {
  python3 -c '
import json
import sys

value = json.load(open(sys.argv[1], encoding="utf-8"))

for part in sys.argv[2].split("."):
    value = value[part]

if isinstance(value, bool):
    print("true" if value else "false")
else:
    print(value)
' "$1" "$2"
}

for required in \
  "$CANONICAL_STATE" \
  "$FAILED_FACTS" \
  "$TRACEBACK_JSON" \
  "$CANONICAL_CURRENT/index.html" \
  "$CANONICAL_CURRENT/canonical-manifest.json"
do
  [ -s "$required" ] || {
    echo "STOP: отсутствует $required"
    exit 2
  }
done

EXPECTED_ID="$(state_value VM101_CANONICAL_ID)"
EXPECTED_WORKSPACE="$(state_value VM101_CANONICAL_PRIVATE_WORKSPACE)"

FAILED_WORKSPACE="$(
  json_value "$FAILED_FACTS" canonical.workspace
)"

TRACEBACK_REASON="$(
  python3 -c '
import json
import sys

data = json.load(open(sys.argv[1], encoding="utf-8"))
tail = data.get("stderr_tail", [])
print(tail[-1] if tail else "UNKNOWN")
' "$TRACEBACK_JSON"
)"

CURRENT_MANIFEST_ID="$(
  json_value \
    "$CANONICAL_CURRENT/canonical-manifest.json" \
    canonical_id
)"

CURRENT_INDEX_ID="$(
  python3 -c '
import re
import sys
from pathlib import Path

text = Path(sys.argv[1]).read_text(
    encoding="utf-8",
    errors="replace",
)

patterns = [
    r"Canonical ID:\s*<code>([^<]+)</code>",
    r"Canonical ID:\s*`([^`]+)`",
]

for pattern in patterns:
    match = re.search(pattern, text)

    if match:
        print(match.group(1))
        raise SystemExit(0)

print("UNRESOLVED")
' "$CANONICAL_CURRENT/index.html"
)"

EXPECTED_SNAPSHOT="$PUBROOT/vm101-canonical/snapshots/$EXPECTED_ID"

if [ -s "$EXPECTED_SNAPSHOT/canonical-manifest.json" ]; then
  SNAPSHOT_MANIFEST_ID="$(
    json_value \
      "$EXPECTED_SNAPSHOT/canonical-manifest.json" \
      canonical_id
  )"
else
  SNAPSHOT_MANIFEST_ID="MISSING"
fi

if [ -x "$ROOT/bin/vm101-canonical-validate" ]; then
  set +e

  "$ROOT/bin/vm101-canonical-validate" \
    > "$REPORT_DIR/current-validator.txt" \
    2>&1

  VALIDATOR_RC=$?

  set -e
else
  VALIDATOR_RC=127
  printf '%s\n' \
    "validator missing" \
    > "$REPORT_DIR/current-validator.txt"
fi

SOURCE="$FAILED_WORKSPACE/source/root/hmn/hmn-refresh-pool-safe.sh"

[ -s "$SOURCE" ] || {
  echo "STOP: отсутствует failed source $SOURCE"
  exit 3
}

SOURCE_SHA="$(
  sha256sum "$SOURCE" |
    cut -d' ' -f1
)"

LOCKED_SHA="$(
  awk -F '\t' \
    '$1 == "refresh_pool_safe" {print $3}' \
    "$FAILED_WORKSPACE/contracts/source-locks.tsv"
)"

LITERAL_ASSUMPTION_COUNT="$(
  grep -F -c \
    '/root/hmn/backups/refresh-safe-before-' \
    "$SOURCE" ||
  true
)"

BACKUPDIR_ASSIGNMENT_COUNT="$(
  grep -F -c \
    'BACKUPDIR="$BASE/backups"' \
    "$SOURCE" ||
  true
)"

BACK_ASSIGNMENT_COUNT="$(
  grep -F -c \
    'BACK="$BACKUPDIR/refresh-safe-before-$TS-$$"' \
    "$SOURCE" ||
  true
)"

SOURCE_LOCK_MATCH=false

if [ "$SOURCE_SHA" = "$LOCKED_SHA" ]; then
  SOURCE_LOCK_MATCH=true
fi

CURRENT_CONSISTENT=false

if [ "$EXPECTED_ID" = "$CURRENT_MANIFEST_ID" ] &&
   [ "$EXPECTED_ID" = "$CURRENT_INDEX_ID" ] &&
   [ "$EXPECTED_ID" = "$SNAPSHOT_MANIFEST_ID" ] &&
   [ "$VALIDATOR_RC" -eq 0 ]
then
  CURRENT_CONSISTENT=true
fi

QUARANTINE_RECORD="$QUARANTINE_ROOT/20260712-092211_vm101_m07_canonical_v2_candidates.env"

printf '%s\n' \
  "status=QUARANTINED_FAILED_GENERATOR" \
  "workspace=$FAILED_WORKSPACE" \
  "reason=$TRACEBACK_REASON" \
  "vm101_contacted=false" \
  "vm101_modified=false" \
  "canonical_current_updated=false" \
  "created_utc=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
  > "$QUARANTINE_RECORD"

chmod 600 "$QUARANTINE_RECORD"

printf '%s\n' \
  "# M07 workflow policy" \
  "" \
  "1. Один target-файл на один generation STEP." \
  "2. До генерации проверяется точный source SHA256." \
  "3. Transform работает по точному AST/assignment/function anchor, а не по придуманному абсолютному пути." \
  "4. Сначала transformer test на private source, затем полный STEP." \
  "5. SHA256SUMS создаётся только после последнего изменения workspace." \
  "6. State-файлы читаются по ключам; выполнять source запрещено." \
  "7. Publication current выполняется только после независимого validator PASS." \
  "8. VM101 installation разрешается отдельным STEP после review diff." \
  > "$WORKFLOW_ROOT/policy.md"

printf '%s\n' \
  "M07_WORKFLOW_STATUS=RECOVERY_MODE_SINGLE_TARGET" \
  "M07_WORKFLOW_AUDIT=$AUDIT_PRIVATE" \
  "M07_KNOWN_GOOD_CANONICAL_ID=$EXPECTED_ID" \
  "M07_FAILED_WORKSPACE=$FAILED_WORKSPACE" \
  "M07_NEXT_TARGET=refresh_pool_safe" \
  "M07_NEXT_STEP=BUILD_AND_TEST_REFRESH_POOL_SAFE_ONLY" \
  > "$STATE_ROOT/current-m07-workflow.env"

chmod 600 \
  "$WORKFLOW_ROOT/policy.md" \
  "$STATE_ROOT/current-m07-workflow.env"

printf '%s\n' \
  "expected_id=$EXPECTED_ID" \
  "current_manifest_id=$CURRENT_MANIFEST_ID" \
  "current_index_id=$CURRENT_INDEX_ID" \
  "snapshot_manifest_id=$SNAPSHOT_MANIFEST_ID" \
  "validator_rc=$VALIDATOR_RC" \
  "current_consistent=$CURRENT_CONSISTENT" \
  "failed_workspace=$FAILED_WORKSPACE" \
  "traceback_reason=$TRACEBACK_REASON" \
  "source=$SOURCE" \
  "source_sha256=$SOURCE_SHA" \
  "locked_sha256=$LOCKED_SHA" \
  "source_lock_match=$SOURCE_LOCK_MATCH" \
  "literal_assumption_count=$LITERAL_ASSUMPTION_COUNT" \
  "backupdir_assignment_count=$BACKUPDIR_ASSIGNMENT_COUNT" \
  "back_assignment_count=$BACK_ASSIGNMENT_COUNT" \
  > "$AUDIT_PRIVATE/audit.env"

cp -a \
  "$AUDIT_PRIVATE/audit.env" \
  "$REPORT_DIR/audit.env"

cp -a \
  "$WORKFLOW_ROOT/policy.md" \
  "$REPORT_DIR/workflow-policy.md"

python3 -c '
import json
import sys
from pathlib import Path

(
    output,
    step,
    expected_id,
    current_manifest_id,
    current_index_id,
    snapshot_manifest_id,
    validator_rc,
    current_consistent,
    failed_workspace,
    traceback_reason,
    source_sha,
    locked_sha,
    source_lock_match,
    literal_count,
    backupdir_count,
    back_count,
    report,
    report_txt,
    facts,
    reference,
    canonical,
) = sys.argv[1:]

data = {
    "schema": "router-step-facts-v1",
    "step": step,
    "assessment": {
        "decision": f"PASS_{step}",
        "step_execution": "PASS",
        "operation_result": "WORKFLOW_FAILURE_CHAIN_AUDITED_AND_FROZEN",
        "production_health": "UNCHANGED",
        "milestone_status": "M07_IN_PROGRESS",
        "all_ok": True,
    },
    "diagnosis": {
        "production_workflow_broken": False,
        "development_workflow_regressed": True,
        "root_cause": "MONOLITHIC_UNTESTED_TEXT_TRANSFORM_GENERATOR",
        "latest_failure": traceback_reason,
        "hardcoded_literal_present":
            int(literal_count) > 0,
        "actual_backupdir_assignment_present":
            int(backupdir_count) > 0,
        "actual_backup_assignment_present":
            int(back_count) > 0,
        "source_lock_match":
            source_lock_match == "true",
    },
    "canonical_publication": {
        "expected_id": expected_id,
        "current_manifest_id": current_manifest_id,
        "current_index_id": current_index_id,
        "snapshot_manifest_id": snapshot_manifest_id,
        "validator_rc": int(validator_rc),
        "consistent":
            current_consistent == "true",
    },
    "workflow_reset": {
        "status": "RECOVERY_MODE_SINGLE_TARGET",
        "failed_workspace": failed_workspace,
        "failed_workspace_quarantined": True,
        "next_target": "refresh_pool_safe",
        "next_step":
            "BUILD_AND_TEST_REFRESH_POOL_SAFE_ONLY",
    },
    "integrity": {
        "source_sha256": source_sha,
        "locked_sha256": locked_sha,
    },
    "safety": {
        "local_only": True,
        "vm101_contacted": False,
        "vm101_modified": False,
        "canonical_current_modified": False,
        "canonical_state_modified": False,
        "installation_allowed": False,
        "network_changed": False,
        "services_changed": False,
        "runtime_state_changed": False,
    },
    "publish": {
        "trycf_report": report,
        "report_txt": report_txt,
        "facts_json": facts,
        "vm101_reference": reference,
        "vm101_canonical": canonical,
    },
}

Path(output).write_text(
    json.dumps(
        data,
        ensure_ascii=False,
        indent=2,
    ) + "\n",
    encoding="utf-8",
)
' \
  "$REPORT_DIR/facts.json" \
  "$STEP" \
  "$EXPECTED_ID" \
  "$CURRENT_MANIFEST_ID" \
  "$CURRENT_INDEX_ID" \
  "$SNAPSHOT_MANIFEST_ID" \
  "$VALIDATOR_RC" \
  "$CURRENT_CONSISTENT" \
  "$FAILED_WORKSPACE" \
  "$TRACEBACK_REASON" \
  "$SOURCE_SHA" \
  "$LOCKED_SHA" \
  "$SOURCE_LOCK_MATCH" \
  "$LITERAL_ASSUMPTION_COUNT" \
  "$BACKUPDIR_ASSIGNMENT_COUNT" \
  "$BACK_ASSIGNMENT_COUNT" \
  "$TRYCF_REPORT" \
  "$REPORT_TXT" \
  "$FACTS_JSON" \
  "$VM101_REFERENCE" \
  "$VM101_CANONICAL"

printf '%s\n' \
  "=== $STEP RESULT ===" \
  "decision=PASS_$STEP" \
  "step_execution=PASS" \
  "operation_result=WORKFLOW_FAILURE_CHAIN_AUDITED_AND_FROZEN" \
  "production_health=UNCHANGED" \
  "milestone_status=M07_IN_PROGRESS" \
  "" \
  "diagnosis:" \
  "  production_workflow_broken=false" \
  "  development_workflow_regressed=true" \
  "  root_cause=MONOLITHIC_UNTESTED_TEXT_TRANSFORM_GENERATOR" \
  "  latest_failure=$TRACEBACK_REASON" \
  "" \
  "canonical_publication:" \
  "  expected_id=$EXPECTED_ID" \
  "  current_manifest_id=$CURRENT_MANIFEST_ID" \
  "  current_index_id=$CURRENT_INDEX_ID" \
  "  snapshot_manifest_id=$SNAPSHOT_MANIFEST_ID" \
  "  validator_rc=$VALIDATOR_RC" \
  "  consistent=$CURRENT_CONSISTENT" \
  "" \
  "refresh_pool_safe:" \
  "  source_lock_match=$SOURCE_LOCK_MATCH" \
  "  literal_assumption_count=$LITERAL_ASSUMPTION_COUNT" \
  "  backupdir_assignment_count=$BACKUPDIR_ASSIGNMENT_COUNT" \
  "  back_assignment_count=$BACK_ASSIGNMENT_COUNT" \
  "" \
  "workflow_reset:" \
  "  status=RECOVERY_MODE_SINGLE_TARGET" \
  "  failed_workspace_quarantined=true" \
  "  next_target=refresh_pool_safe" \
  "  next_step=BUILD_AND_TEST_REFRESH_POOL_SAFE_ONLY" \
  "" \
  "safety:" \
  "  local_only=true" \
  "  vm101_contacted=false" \
  "  vm101_modified=false" \
  "  canonical_current_modified=false" \
  "  canonical_state_modified=false" \
  "  installation_allowed=false" \
  "" \
  "TRYCF_REPORT=$TRYCF_REPORT" \
  "REPORT_TXT=$REPORT_TXT" \
  "FACTS_JSON=$FACTS_JSON" \
  "VM101_REFERENCE=$VM101_REFERENCE" \
  "VM101_CANONICAL=$VM101_CANONICAL" \
  > "$REPORT_DIR/report.txt"

printf '%s\n' \
  '<!doctype html>' \
  '<html lang="ru"><head><meta charset="utf-8"><title>Workflow audit</title></head>' \
  '<body style="font-family:system-ui;max-width:1000px;margin:40px auto">' \
  "<h1>$STEP</h1>" \
  '<ul>' \
  '<li><a href="report.txt">report.txt</a></li>' \
  '<li><a href="facts.json">facts.json</a></li>' \
  '<li><a href="audit.env">audit.env</a></li>' \
  '<li><a href="workflow-policy.md">workflow-policy.md</a></li>' \
  '<li><a href="current-validator.txt">current-validator.txt</a></li>' \
  '<li><a href="step.sh">step.sh</a></li>' \
  '</ul></body></html>' \
  > "$REPORT_DIR/index.html"

find "$REPORT_DIR" \
  -type f \
  ! -name SHA256SUMS \
  -print0 |
  sort -z |
  xargs -0 sha256sum \
  > "$REPORT_DIR/SHA256SUMS"

chmod -R a+rX "$REPORT_DIR"

echo "decision=PASS_$STEP"
echo "operation_result=WORKFLOW_FAILURE_CHAIN_AUDITED_AND_FROZEN"
echo "production_workflow_broken=false"
echo "development_workflow_regressed=true"
echo "current_consistent=$CURRENT_CONSISTENT"
echo "source_lock_match=$SOURCE_LOCK_MATCH"
echo "literal_assumption_count=$LITERAL_ASSUMPTION_COUNT"
echo "backupdir_assignment_count=$BACKUPDIR_ASSIGNMENT_COUNT"
echo "back_assignment_count=$BACK_ASSIGNMENT_COUNT"
echo "workflow_status=RECOVERY_MODE_SINGLE_TARGET"
echo "next_target=refresh_pool_safe"
echo "vm101_contacted=false"
echo "vm101_modified=false"

echo
echo "TRYCF_REPORT=$TRYCF_REPORT"
echo "REPORT_TXT=$REPORT_TXT"
echo "FACTS_JSON=$FACTS_JSON"
echo "VM101_REFERENCE=$VM101_REFERENCE"
echo "VM101_CANONICAL=$VM101_CANONICAL"
