package compatibility

import (
	"strings"
	"testing"

	runtimev1 "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/runtime/v1"
	"google.golang.org/protobuf/reflect/protoreflect"
)

func TestLayoutAuthoringWirePublishesOnlyTheDedicatedTypedLifecycle(t *testing.T) {
	request := (&runtimev1.LayoutAuthoringServiceSubmitRequest{}).ProtoReflect().Descriptor()
	assertFieldNames(t, request.Fields(), []protoreflect.Name{
		"command_id", "idempotency_key", "base_catalog_revision", "wait_mode",
		"create", "update", "clone", "set_default", "delete", "restore", "assignment_upsert", "assignment_delete",
	})
	operation := request.Oneofs().ByName("operation")
	if operation == nil || operation.Fields().Len() != 8 {
		t.Fatalf("operation oneof = %#v", operation)
	}

	viewRef := (&runtimev1.LayoutAuthoringCatalogViewRef{}).ProtoReflect().Descriptor()
	assertFieldNames(t, viewRef.Fields(), []protoreflect.Name{"catalog_revision", "authoring_view_digest"})

	behaviorGroup := (&runtimev1.LayoutAuthoringFieldBehaviorGroup{}).ProtoReflect().Descriptor()
	assertFieldNames(t, behaviorGroup.Fields(), []protoreflect.Name{"field_reference", "behaviors"})
	if !behaviorGroup.Fields().ByName("behaviors").HasPresence() {
		t.Fatal("field behavior group lost nil-versus-present inner-map presence")
	}

	state := runtimev1.LayoutAuthoringCommandState_LAYOUT_AUTHORING_COMMAND_STATE_UNSPECIFIED.Descriptor().Values()
	wantStates := []protoreflect.Name{
		"LAYOUT_AUTHORING_COMMAND_STATE_UNSPECIFIED", "LAYOUT_AUTHORING_COMMAND_STATE_ACCEPTED",
		"LAYOUT_AUTHORING_COMMAND_STATE_IN_PROGRESS", "LAYOUT_AUTHORING_COMMAND_STATE_SUCCEEDED",
		"LAYOUT_AUTHORING_COMMAND_STATE_FAILED",
	}
	if state.Len() != len(wantStates) {
		t.Fatalf("command state count = %d", state.Len())
	}
	for index, want := range wantStates {
		if got := state.Get(index).Name(); got != want {
			t.Fatalf("command state[%d] = %q, want %q", index, got, want)
		}
	}
	for index := 0; index < state.Len(); index++ {
		name := string(state.Get(index).Name())
		if strings.Contains(name, "PUBLISHING") || strings.Contains(name, "POISONED") {
			t.Fatalf("internal recovery state entered public wire: %q", name)
		}
	}

	wantMethods := map[string]string{
		"submit":        "/nexuscrm.runtime.v1.LayoutAuthoringService/Submit",
		"get command":   "/nexuscrm.runtime.v1.LayoutAuthoringService/GetCommand",
		"workspace":     "/nexuscrm.runtime.v1.LayoutAuthoringService/ReadWorkspace",
		"stored layout": "/nexuscrm.runtime.v1.LayoutAuthoringService/ReadStoredLayout",
	}
	gotMethods := map[string]string{
		"submit":        runtimev1.LayoutAuthoringService_Submit_FullMethodName,
		"get command":   runtimev1.LayoutAuthoringService_GetCommand_FullMethodName,
		"workspace":     runtimev1.LayoutAuthoringService_ReadWorkspace_FullMethodName,
		"stored layout": runtimev1.LayoutAuthoringService_ReadStoredLayout_FullMethodName,
	}
	for name, want := range wantMethods {
		if got := gotMethods[name]; got != want {
			t.Fatalf("%s method = %q, want %q", name, got, want)
		}
	}
}

func TestLayoutAuthoringCreateContextIsReadOnlyAndPresenceBearing(t *testing.T) {
	stored := (&runtimev1.LayoutAuthoringServiceReadStoredLayoutResponse{}).ProtoReflect().Descriptor()
	context := stored.Fields().ByName("create_context")
	if context == nil || context.Number() != 9 || !context.HasPresence() {
		t.Fatal("stored create context must be an additive presence-bearing field")
	}
	assertFieldNames(t, context.Message().Fields(), []protoreflect.Name{"required_fields"})
	for _, message := range []protoreflect.MessageDescriptor{
		(&runtimev1.LayoutAuthoringDocument{}).ProtoReflect().Descriptor(),
		(&runtimev1.LayoutAuthoringDocumentChanges{}).ProtoReflect().Descriptor(),
		(&runtimev1.LayoutAuthoringLayoutSnapshot{}).ProtoReflect().Descriptor(),
	} {
		if message.Fields().ByName("create_context") != nil {
			t.Fatalf("read-only context leaked into writable or command result shape %s", message.FullName())
		}
	}
}
