package runtimeassembly

import (
	"github.com/nexuscrm/metadata"
	"github.com/nexuscrm/shared/pkg/models"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/layoutauthoringv2"
	"strings"
	"testing"
)

func TestLayoutAuthoringExistingAssignmentNoOpMatchesWireContract(t *testing.T) {
	profile := "profile-admin"
	requestedProfile := "PROFILE-ADMIN"
	revision := "sha256:" + strings.Repeat("a", 64)
	before := metadata.LayoutAuthoringAggregateSnapshot{
		ObjectAPIName: "Account",
		Layouts:       []*models.PageLayout{{ID: "layout-a", ObjectAPIName: "Account"}},
		Assignments:   []*models.LayoutAssignment{{ID: "assignment-a", ObjectAPIName: "Account", LayoutID: "layout-a", ProfileID: &profile}},
	}
	request := semantic.Request{ObjectID: "Account", ExpectedLayoutRevision: revision, Operation: semantic.Operation{AssignmentUpsert: &semantic.UpsertLayoutAssignment{LayoutID: "layout-a", Selectors: semantic.AssignmentSelectors{ProfileID: &requestedProfile}}}}
	engine := &LayoutAuthoringEngine{metadata: &metadata.MetadataService{}}
	changed, layoutID, assignmentID, _, _, err := engine.apply(t.Context(), "admin", request, before)
	if err != nil {
		t.Fatal(err)
	}
	response := semantic.Response{Changed: changed, LayoutRevision: revision, LayoutID: layoutID, AssignmentID: assignmentID, Receipts: semantic.Receipts{ProtocolVersion: "1.0", CapabilityVersion: semantic.CapabilityName}}
	if err := semantic.ValidateResponse(request, response); err != nil {
		t.Fatalf("existing assignment no-op cannot cross Runtime response boundary: changed=%v layoutID=%v assignmentID=%v error=%v", changed, layoutID, assignmentID, err)
	}
}

func TestLayoutAuthoringRoutingAcceptsEquivalentSelectorIdentity(t *testing.T) {
	profile, recordType := "PROFILE-A", "RECORD-TYPE-A"
	snapshot := metadata.LayoutAuthoringAggregateSnapshot{Layouts: []*models.PageLayout{{ID: "layout-a", Type: "Detail"}}}
	operation := semantic.Operation{AssignmentUpsert: &semantic.UpsertLayoutAssignment{LayoutID: "layout-a", Selectors: semantic.AssignmentSelectors{ProfileID: &profile, RecordTypeID: &recordType}}}
	for _, test := range []struct {
		name                  string
		profiles, recordTypes map[string]bool
		wantError             bool
	}{
		{"live selectors", map[string]bool{"profile-a": true}, map[string]bool{"record-type-a": true}, false},
		{"absent profile", nil, map[string]bool{"record-type-a": true}, true},
		{"inactive record type", map[string]bool{"profile-a": true}, nil, true},
	} {
		t.Run(test.name, func(t *testing.T) {
			err := validateChangedLayoutRouting(snapshot, operation, test.profiles, test.recordTypes, nil, t.Context())
			if (err != nil) != test.wantError {
				t.Fatalf("routing validation error=%v", err)
			}
		})
	}
}
