#!/usr/bin/env bash
# HA custom `!tag` round-trip test for scripts/ha/lib/normalize.py.
#
# yaml.safe_load has no constructor for HA's `!include` / `!secret` / etc.
# tags and raises ConstructorError on them. normalize.py must parse them
# generically (scalar, sequence, and mapping payloads) and re-dump the same
# tag + payload, with normalization staying deterministic across repeated
# passes. Quoting style of tagged scalars is allowed to change (normalize.py
# reformats the whole document already); what must not change is the tag
# itself and the parsed value it carries.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HA_LIB_DIR="$SCRIPT_DIR/../lib"
FIXTURE="$SCRIPT_DIR/fixtures/configuration.yaml"

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

fail=0

if ! python3 "$HA_LIB_DIR/normalize.py" yaml "$FIXTURE" > "$TMP/pass1.yaml" 2> "$TMP/pass1.err"; then
  echo "FAIL: normalize.py raised on a configuration.yaml with custom HA tags" >&2
  cat "$TMP/pass1.err" >&2
  fail=1
else
  echo "PASS: normalize.py parses custom HA tags without ConstructorError"
fi

expected_tags=(
  "!include"
  "!include_dir_merge_named"
  "!secret"
  "!fake_mapping_tag"
  "!fake_sequence_tag"
)
for tag in "${expected_tags[@]}"; do
  if ! grep -qF "$tag" "$TMP/pass1.yaml"; then
    echo "FAIL: expected tag '$tag' missing from normalized output" >&2
    fail=1
  fi
done
if [[ "$fail" -eq 0 ]]; then
  echo "PASS: all custom tags present in normalized output"
fi

# Structural round-trip: parsing the normalized output back through the same
# loader must yield the exact same tagged values (scalar/sequence/mapping
# payloads) as parsing the original fixture — normalization must not lose or
# mutate data carried under a custom tag.
if ! python3 - "$HA_LIB_DIR" "$FIXTURE" "$TMP/pass1.yaml" <<'PYEOF'
import sys

lib_dir, fixture_path, normalized_path = sys.argv[1:4]
sys.path.insert(0, lib_dir)
from normalize import parse_yaml_text

with open(fixture_path, encoding="utf-8") as f:
    original = parse_yaml_text(f.read())
with open(normalized_path, encoding="utf-8") as f:
    normalized = parse_yaml_text(f.read())

if original != normalized:
    print(f"structural mismatch:\noriginal:  {original!r}\nnormalized: {normalized!r}", file=sys.stderr)
    sys.exit(1)
PYEOF
then
  echo "FAIL: normalized output does not structurally round-trip to the original tagged values" >&2
  fail=1
else
  echo "PASS: normalized output structurally round-trips (tags + payloads unchanged)"
fi

# Idempotency: normalizing the already-normalized output a second time must
# produce byte-identical text (tags preserved through N passes).
if ! python3 "$HA_LIB_DIR/normalize.py" yaml "$TMP/pass1.yaml" > "$TMP/pass2.yaml" 2> "$TMP/pass2.err"; then
  echo "FAIL: second normalization pass raised on its own output" >&2
  cat "$TMP/pass2.err" >&2
  fail=1
elif ! diff "$TMP/pass1.yaml" "$TMP/pass2.yaml" > /dev/null; then
  echo "FAIL: normalize.py is not idempotent across two passes" >&2
  diff "$TMP/pass1.yaml" "$TMP/pass2.yaml" >&2 || true
  fail=1
else
  echo "PASS: normalize.py output is byte-identical across two passes"
fi

exit "$fail"
