package hub

// S3 Group C — the wireguard desired-state block contract. testdata/desired-state-wireguard.
// golden.json MUST stay byte-identical with felhom.eu/hub's copy (the established cross-repo
// duplication rule); this test decodes it through the new WireWireguard struct field-exactly
// and key-set-compares to catch drift.

import (
	"encoding/json"
	"os"
	"testing"
)

func TestDesiredStateWireguardGolden_DecodesFieldExact(t *testing.T) {
	raw, err := os.ReadFile("testdata/desired-state-wireguard.golden.json")
	if err != nil {
		t.Fatal(err)
	}
	var resp DesiredStateResponse
	if err := json.Unmarshal(raw, &resp); err != nil {
		t.Fatalf("wireguard golden does not decode into DesiredStateResponse: %v", err)
	}
	wg := resp.DesiredState.Wireguard
	if wg == nil {
		t.Fatal("wireguard block missing after decode")
	}
	if wg.Pubkey != "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=" {
		t.Errorf("pubkey = %q", wg.Pubkey)
	}
	if wg.AssignedIP != "10.77.0.2/32" {
		t.Errorf("assigned_ip = %q", wg.AssignedIP)
	}
	ep := wg.Endpoint
	if ep.DNSName != "ep0.felhom.eu" || ep.WGPort != 443 ||
		ep.ServerPubkey != "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk=" || ep.PBSTunnelIP != "10.77.0.1" {
		t.Errorf("endpoint = %+v", ep)
	}
	// The base (non-wireguard) content of the golden is the S2 superset of the original
	// desired-state golden — the pre-existing fields must still decode.
	if len(resp.DesiredState.Guests) != 2 || resp.DesiredState.PBSNamespace != "felhom-cust-acme" {
		t.Errorf("base fields lost: guests=%d ns=%q", len(resp.DesiredState.Guests), resp.DesiredState.PBSNamespace)
	}

	// Key-set drift guard for the wireguard object + its endpoint.
	var golden map[string]any
	json.Unmarshal(raw, &golden)
	b, _ := json.Marshal(resp)
	var got map[string]any
	json.Unmarshal(b, &got)
	assertSameKeys(t, "desired_state.wireguard",
		golden["desired_state"].(map[string]any)["wireguard"],
		got["desired_state"].(map[string]any)["wireguard"])
	assertSameKeys(t, "desired_state.wireguard.endpoint",
		golden["desired_state"].(map[string]any)["wireguard"].(map[string]any)["endpoint"],
		got["desired_state"].(map[string]any)["wireguard"].(map[string]any)["endpoint"])
}
