package layoutvalidationviewv1

import (
	"github.com/pingcap-inc/nexuscrm-contract/pkg/catalogassignmentidentityv1"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/catalogpublicationv1"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/layoutbundlekeyv1"
)

const (
	CanonicalizationVersion       = "nexuscrm.layout-validation-view-canonical/v1"
	KeyGrammarVersion             = "nexuscrm.layout-validation-key/v1"
	ObjectKeyNormalizationVersion = catalogassignmentidentityv1.ObjectKeyNormalizationVersion
	FieldKeyNormalizationVersion  = "nexuscrm.catalog-field-key-normalization/v1"

	AppAuthorityEvidenceVersion    = "nexuscrm.layout-bundle-app-authority-evidence/v1"
	TenantAuthorityEvidenceVersion = "nexuscrm.layout-bundle-tenant-authority-evidence/v1"
	SystemAuthorityEvidenceVersion = "nexuscrm.layout-bundle-system-authority-evidence/v1"

	MaxFieldAPINameBytes                        = 64
	MaxPolymorphicOwnerFieldAPINameBytes        = 59
	MaxEntriesPerArray                          = 100_000
	MaxCanonicalViewBytes                uint64 = 128 << 20
)

// ObjectKey is the exact Catalog assignment-identity object key. An alias is
// used so the two contracts cannot drift into merely similar grammars.
type ObjectKey = catalogassignmentidentityv1.ObjectKey

// FieldKey is one normalized field identity within a normalized object.
type FieldKey struct {
	ObjectKey              ObjectKey
	NormalizedFieldAPIName string
}

// NamespacedContractKey identifies a registered action or renderer contract.
type NamespacedContractKey struct {
	NamespaceID string
	LocalKey    string
}

// CapabilityID, DataTypeID, ActionKindID, and LayoutFormatVersion share the
// versioned neutral capability-ID grammar but remain semantically distinct.
type CapabilityID string
type DataTypeID string
type ActionKindID string
type LayoutFormatVersion string

type ObjectContract struct {
	Key          ObjectKey
	Capabilities []CapabilityID
}

type RelationshipKind string

const (
	RelationshipKindNone         RelationshipKind = "NONE"
	RelationshipKindLookup       RelationshipKind = "LOOKUP"
	RelationshipKindMasterDetail RelationshipKind = "MASTER_DETAIL"
)

type FieldContract struct {
	Key                          FieldKey
	DataTypeID                   DataTypeID
	RelationshipKind             RelationshipKind
	OwnsPolymorphicDiscriminator bool
	RequiredOnCreate             bool
	Nillable                     bool
	DefaultedOnCreate            bool
	Createable                   bool
	Updateable                   bool
	EditContractKey              *NamespacedContractKey
	RenderContractKey            NamespacedContractKey
	ReferenceTargets             []ObjectKey
}

type RelationshipContract struct {
	ReferenceFieldKey FieldKey
	TargetObjectKey   ObjectKey
	Kind              RelationshipKind
}

type RelatedListContract struct {
	ParentObjectKey   ObjectKey
	ReferenceFieldKey FieldKey
	Capabilities      []CapabilityID
}

type ActionContract struct {
	ObjectKey       ObjectKey
	Key             NamespacedContractKey
	ActionKindID    ActionKindID
	TargetObjectKey *ObjectKey
	ContractVersion uint64
	ContractDigest  string
	Capabilities    []CapabilityID
}

type RendererComponentContract struct {
	Key             NamespacedContractKey
	ContractVersion uint64
	ContractDigest  string
	Capabilities    []CapabilityID
}

type LayoutFormatContract struct {
	LayoutFormatVersion LayoutFormatVersion
	ContractDigest      string
}

type BundleAuthorityEvidenceRef struct {
	BundleKey       layoutbundlekeyv1.BundleKey
	EvidenceVersion string
	EvidenceDigest  string
}

// View is the complete immutable v1 validation projection for one exact
// Catalog snapshot. Every slice, including nested slices, must be present.
type View struct {
	CanonicalizationVersion             string
	KeyGrammarVersion                   string
	ObjectKeyNormalizationVersion       string
	FieldKeyNormalizationVersion        string
	SourceCatalogSnapshot               catalogpublicationv1.CatalogSnapshotBinding
	CatalogAssignmentIdentityViewDigest string
	RequiredBundleKeySetDigest          string
	Objects                             []ObjectContract
	Fields                              []FieldContract
	Relationships                       []RelationshipContract
	RelatedLists                        []RelatedListContract
	Actions                             []ActionContract
	RendererComponents                  []RendererComponentContract
	AcceptedLayoutFormats               []LayoutFormatContract
	BundleAuthorityEvidence             []BundleAuthorityEvidenceRef
}
