package materializer

import (
	"strings"
	"testing"
)

func TestCanonicalSha256_StableAcrossMapOrder(t *testing.T) {
	a := map[string]any{"b": 2, "a": 1, "c": map[string]any{"y": "Y", "x": "X"}}
	b := map[string]any{"a": 1, "c": map[string]any{"x": "X", "y": "Y"}, "b": 2}
	hashA, err := CanonicalSha256(a)
	if err != nil {
		t.Fatalf("hash a: %v", err)
	}
	hashB, err := CanonicalSha256(b)
	if err != nil {
		t.Fatalf("hash b: %v", err)
	}
	if hashA != hashB {
		t.Fatalf("identical objects produced different hashes:\n  a=%s\n  b=%s", hashA, hashB)
	}
	if len(hashA) != 64 || strings.Trim(hashA, "0123456789abcdef") != "" {
		t.Fatalf("hash isn't a 64-char hex string: %q", hashA)
	}
}

func TestCanonicalSha256_DistinctsDifferentInputs(t *testing.T) {
	a := map[string]any{"k": "v"}
	b := map[string]any{"k": "v2"}
	hashA, _ := CanonicalSha256(a)
	hashB, _ := CanonicalSha256(b)
	if hashA == hashB {
		t.Fatalf("different inputs collided: %s", hashA)
	}
}

func TestCanonicalSha256_ArrayOrderMatters(t *testing.T) {
	a := map[string]any{"k": []any{1, 2, 3}}
	b := map[string]any{"k": []any{3, 2, 1}}
	hashA, _ := CanonicalSha256(a)
	hashB, _ := CanonicalSha256(b)
	if hashA == hashB {
		t.Fatal("array order should change the hash, but did not")
	}
}
