package records

import (
	"context"
	"testing"

	"github.com/nexuscrm/metadata"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

type reservedCreateIDCaptureRepo struct {
	nestedRollupBoundaryRepo
	insertedByTable map[string][]models.SObject
}

func (r *reservedCreateIDCaptureRepo) Insert(_ context.Context, tableName string, record models.SObject) error {
	if r.insertedByTable == nil {
		r.insertedByTable = map[string][]models.SObject{}
	}
	r.insertedByTable[tableName] = append(r.insertedByTable[tableName], cloneSObject(record))
	return nil
}

func TestRuntimeReservedCreateIDIsInjectedOnlyWhenCallerIDIsAbsent(t *testing.T) {
	schema := &models.ObjectMetadata{APIName: "WorkItem", Fields: []models.FieldMetadata{{APIName: constants.FieldID, Type: constants.FieldTypeString}}}
	service := &PersistenceService{metadata: metadata.NewMetadataService(&recordIDOwnerMetadataRepo{schema: schema}, nil, nil)}
	ctx := withRuntimeReservedCreateID(context.Background(), "reserved-id")
	got := service.generateSystemFields(ctx, "WorkItem", models.SObject{}, nil, true)
	if got[constants.FieldID] != "reserved-id" {
		t.Fatalf("Id = %#v", got[constants.FieldID])
	}
	caller := service.generateSystemFields(ctx, "WorkItem", models.SObject{constants.FieldID: "already-authorized-internal-id"}, nil, true)
	if caller[constants.FieldID] != "already-authorized-internal-id" {
		t.Fatalf("existing internal Id overwritten: %#v", caller[constants.FieldID])
	}
}

func TestRuntimeReservedCreateIDDoesNotLeakIntoDefaultChildInsert(t *testing.T) {
	repo := &reservedCreateIDCaptureRepo{nestedRollupBoundaryRepo: nestedRollupBoundaryRepo{
		existsAnyByTable: map[string]bool{"Grant__c": true},
		oldByTable: map[string]models.SObject{
			"Grant__c": {constants.FieldID: "reserved-parent-id"},
		},
	}}
	service := newRollupBoundaryTestService(
		repo,
		defaultChildRowParentSchemaForBoundaryTest(),
		rollupChildSchemaWithAdditionalParentsForBoundaryTest(),
	)
	ctx := constants.WithSecurityContext(context.Background(), constants.SystemContext, "reserved outer create")
	created, err := service.Insert(
		withRuntimeReservedCreateID(ctx, "reserved-parent-id"),
		"Grant__c",
		models.SObject{constants.FieldName: "Grant A"},
		recordEntrypointUser(),
	)
	if err != nil {
		t.Fatalf("Insert: %v", err)
	}
	if got := created[constants.FieldID]; got != "reserved-parent-id" {
		t.Fatalf("outer Id = %#v, want reserved-parent-id", got)
	}
	children := repo.insertedByTable["Task__c"]
	if len(children) != 1 {
		t.Fatalf("child insert count = %d, want 1", len(children))
	}
	childID, _ := children[0][constants.FieldID].(string)
	if childID == "" || childID == "reserved-parent-id" {
		t.Fatalf("child Id = %q, want a generated identity distinct from the outer reservation", childID)
	}
	if got := children[0]["GrantId__c"]; got != "reserved-parent-id" {
		t.Fatalf("child GrantId__c = %#v, want reserved-parent-id", got)
	}
}
