package catalogpublicationv1

import (
	"reflect"
	"testing"

	"github.com/pingcap-inc/nexuscrm-contract/pkg/internal/testvectors"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/layoutroutingsecurityv1"
)

func TestPublicationComponentBindingsOwnOnlyCrossAuthorityIdentity(t *testing.T) {
	testvectors.AssertFields(t, reflect.TypeOf(CatalogSnapshotBinding{}), []string{
		"OrgID", "CatalogRevision", "CatalogSnapshotDigest", "SchemaGeneration", "EngineGeneration",
	})
	testvectors.AssertFields(t, reflect.TypeOf(CatalogSchemaBinding{}), []string{
		"CatalogSnapshot", "LayoutValidationViewDigest",
	})
}

func TestBindingComponentsRoundTripWithoutCouplingAxes(t *testing.T) {
	binding := validBinding()
	catalog, activationDigest, security, err := BindingComponents(binding)
	if err != nil {
		t.Fatal(err)
	}
	if catalog.CatalogSnapshot.CatalogRevision != binding.CatalogRevision ||
		security.SecurityEpoch != binding.SecurityEpoch || activationDigest != binding.LayoutActivationSetDigest {
		t.Fatalf("components lost publication identity: %#v %q %#v", catalog, activationDigest, security)
	}
	recomposed, err := ComposeBinding(catalog, activationDigest, security)
	if err != nil {
		t.Fatal(err)
	}
	if recomposed != binding {
		t.Fatalf("recomposed binding = %#v, want %#v", recomposed, binding)
	}

	catalog.CatalogSnapshot.CatalogRevision = 1
	security.SecurityEpoch = ^uint64(0)
	if _, err := ComposeBinding(catalog, activationDigest, security); err != nil {
		t.Fatalf("independent axes rejected: %v", err)
	}
}

func TestBindingFromComponentsRejectsCrossOrgComposition(t *testing.T) {
	catalog, activationDigest, security, err := BindingComponents(validBinding())
	if err != nil {
		t.Fatal(err)
	}
	security.OrgID = "org-2"
	if _, err := ComposeBinding(catalog, activationDigest, security); err == nil {
		t.Fatal("cross-org publication composition accepted")
	}
}

func TestComponentValidationRejectsIncompleteIdentity(t *testing.T) {
	catalog, _, security, err := BindingComponents(validBinding())
	if err != nil {
		t.Fatal(err)
	}

	catalog.CatalogSnapshot.SchemaGeneration = 0
	if err := ValidateCatalogSchemaBinding(catalog); err == nil {
		t.Fatal("incomplete Catalog schema binding accepted")
	}
	security.LayoutRoutingSecurityViewDigest = "sha256:INVALID"
	if err := layoutroutingsecurityv1.ValidateBinding(security); err == nil {
		t.Fatal("incomplete routing-security binding accepted")
	}
}
