package consumerv1

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

func TestEffectiveStandardFlowDocumentRoundTrip(t *testing.T) {
	behavior := []byte(`{"runAtomically":true,"status":"Active"}`)
	encoded, err := EncodeEffectiveStandardFlowDocument("7", behavior)
	if err != nil {
		t.Fatal(err)
	}
	document, err := DecodeEffectiveStandardFlowDocument(encoded)
	if err != nil {
		t.Fatal(err)
	}
	if document.DefinitionVersion != "7" ||
		!bytes.Equal(document.CanonicalBehavior, behavior) {
		t.Fatalf("decoded document = %#v", document)
	}
}

func TestEffectiveStandardFlowDocumentPreservesCanonicalBehaviorBytes(t *testing.T) {
	behavior := []byte("{\n  \"expression\": \"left < right && right > 0\"\n}\n")
	encoded, err := EncodeEffectiveStandardFlowDocument("7", behavior)
	if err != nil {
		t.Fatal(err)
	}
	want := append([]byte(`{"definitionVersion":"7","canonicalBehavior":`), behavior...)
	want = append(want, '}')
	if !bytes.Equal(encoded, want) {
		t.Fatalf("encoded envelope = %s, want exact behavior bytes in %s", encoded, want)
	}
	document, err := DecodeEffectiveStandardFlowDocument(encoded)
	if err != nil {
		t.Fatal(err)
	}
	if !bytes.Equal(document.CanonicalBehavior, behavior) {
		t.Fatalf("decoded behavior = %s, want %s", document.CanonicalBehavior, behavior)
	}
}

func TestEffectiveStandardFlowDocumentFailsClosed(t *testing.T) {
	for _, test := range []struct {
		name    string
		encoded []byte
	}{
		{name: "zero version", encoded: []byte(`{"definitionVersion":"0","canonicalBehavior":{}}`)},
		{name: "noncanonical version", encoded: []byte(`{"definitionVersion":"01","canonicalBehavior":{}}`)},
		{name: "unknown field", encoded: []byte(`{"definitionVersion":"1","canonicalBehavior":{},"extra":true}`)},
		{name: "noncanonical envelope", encoded: []byte(`{ "definitionVersion":"1", "canonicalBehavior":{} }`)},
		{name: "trailing JSON", encoded: []byte(`{"definitionVersion":"1","canonicalBehavior":{}} {}`)},
	} {
		t.Run(test.name, func(t *testing.T) {
			if _, err := DecodeEffectiveStandardFlowDocument(test.encoded); err == nil {
				t.Fatal("expected rejection")
			}
		})
	}
}

func TestEffectiveStandardFlowDocumentRejectsInvalidUTF8(t *testing.T) {
	behavior := []byte{'{', '"', 'l', 'a', 'b', 'e', 'l', '"', ':', '"', 0xff, '"', '}'}
	if !json.Valid(behavior) {
		t.Fatal("test input must demonstrate that JSON syntax validation alone accepts invalid UTF-8")
	}
	if _, err := EncodeEffectiveStandardFlowDocument("1", behavior); err == nil {
		t.Fatal("expected invalid UTF-8 rejection")
	}
}
