package packspec

import (
	"encoding/json"
	"testing"
)

// CoerceSpecDefault is the sole gate between the embedded JSON spec and the
// downstream writers (reconcileStandardFieldDefaultValues, drift verifier).
// A regression here — treating empty string as set, crashing on a bare
// JSON number, or mis-handling an unexpected shape — would either corrupt
// live DefaultValue rows or hard-fail bootstrap, so the contract is pinned.
func TestCoerceSpecDefault(t *testing.T) {
	cases := []struct {
		name    string
		raw     string
		wantStr string
		wantOk  bool
	}{
		{"missing", "", "", false},
		{"null", "null", "", false},
		{"null with whitespace", "  null\n", "", false},
		{"empty string", `""`, "", false},
		{"string", `"Draft"`, "Draft", true},
		{"string zero", `"0"`, "0", true},
		{"string literal null", `"null"`, "null", true},
		{"string with apostrophe", `"O'Brien"`, "O'Brien", true},
		{"string with backslash", `"a\\b"`, `a\b`, true},
		{"unicode escape", `"\u0041"`, "A", true},
		{"number", `0`, "0", true},
		{"negative number", `-5`, "-5", true},
		{"float", `1.5`, "1.5", true},
		{"large int", `99999999999999999999`, "99999999999999999999", true},
		{"boolean false", `false`, "false", true},
		{"boolean true", `true`, "true", true},
		{"array", `[1,2]`, "[1,2]", true},
		{"object", `{}`, "{}", true},
		{"malformed string", `"unterminated`, "", false},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got, ok := CoerceSpecDefault(json.RawMessage(tc.raw))
			if ok != tc.wantOk || got != tc.wantStr {
				t.Fatalf("CoerceSpecDefault(%q) = (%q, %v); want (%q, %v)",
					tc.raw, got, ok, tc.wantStr, tc.wantOk)
			}
		})
	}
}
