package automation

// field_default_resolver_test.go — regression tests for Issue #609:
// super-user $Permission injection in the ActionFieldDefault (stage-3) resolver.
//
// Covers Apply() with isSuperUser=true so that $Permission.X references in
// Condition and ValueFormula resolve correctly for super-users — the 5th consumer
// identified in the P1 review comment.

import (
	"context"
	"testing"

	"github.com/nexuscrm/kernel/pkg/formula"
	"github.com/nexuscrm/shared/pkg/models"
	seedrows "github.com/pingcap-inc/nexuscrm-contract/pkg/seedrows"
)

// makeResolverCtx stamps a single ActionFieldDefault row on a context and
// returns both the context and the resolver for use by Apply tests.
func makeResolverCtx(row seedrows.ActionFieldDefaultRow) (context.Context, FieldDefaultResolver) {
	ctx := WithActionFieldDefaults(context.Background(), []seedrows.ActionFieldDefaultRow{row})
	resolver := NewDefaultFieldDefaultResolver(formula.NewEngine())
	return ctx, resolver
}

// TestFieldDefaultResolver_SuperUser_PermissionCondition verifies that when
// isSuperUser=true a row whose Condition references $Permission.SomeGate
// evaluates to true and the field default is written.
// Regression guard for Issue #609 — before the fix, Apply() never received
// isSuperUser so $Permission keys were never injected and the condition always
// evaluated as false for super-users.
func TestFieldDefaultResolver_SuperUser_PermissionCondition(t *testing.T) {
	row := seedrows.ActionFieldDefaultRow{
		TargetObject: "Contact",
		FieldAPIName: "Status__c",
		Condition:    "$Permission.SomeGate",
		ValueFormula: "'Active'",
		Priority:     10,
	}
	ctx, resolver := makeResolverCtx(row)
	record := models.SObject{}

	err := resolver.Apply(ctx, record, "Contact", map[string]interface{}{}, true /* isSuperUser */)
	if err != nil {
		t.Fatalf("Apply() returned unexpected error: %v", err)
	}
	got, ok := record["Status__c"]
	if !ok {
		t.Fatal("Apply(): Status__c was not written; $Permission.SomeGate condition should be true for super-user")
	}
	if got != "Active" {
		t.Errorf("Apply(): Status__c = %q; want %q", got, "Active")
	}
}

// TestFieldDefaultResolver_NonSuperUser_NoPermissionInjection verifies that
// when isSuperUser=false, Apply() does NOT inject $Permission keys — i.e. the
// super-user shortcut is strictly guarded.
//
// We use a row whose Condition is a plain Input expression (no $Permission ref)
// that evaluates to false, and confirm the field is not written.  This confirms
// the isSuperUser=false path executes normally without the injection side-effect.
func TestFieldDefaultResolver_NonSuperUser_NoPermissionInjection(t *testing.T) {
	row := seedrows.ActionFieldDefaultRow{
		TargetObject: "Contact",
		FieldAPIName: "Status__c",
		Condition:    "Input.trigger == 'skip'",
		ValueFormula: "'Active'",
		Priority:     10,
	}
	ctx, resolver := makeResolverCtx(row)
	record := models.SObject{}

	// trigger != 'skip' → condition false → field NOT written.
	inputs := map[string]interface{}{"trigger": "go"}
	err := resolver.Apply(ctx, record, "Contact", inputs, false /* isSuperUser */)
	if err != nil {
		t.Fatalf("Apply() returned unexpected error: %v", err)
	}
	if _, ok := record["Status__c"]; ok {
		t.Error("Apply(): Status__c was written when condition should be false")
	}
}

// TestFieldDefaultResolver_SuperUser_PermissionValueFormula verifies that
// $Permission.X in ValueFormula (no Condition) is also injected for super-users.
func TestFieldDefaultResolver_SuperUser_PermissionValueFormula(t *testing.T) {
	row := seedrows.ActionFieldDefaultRow{
		TargetObject: "Lead",
		FieldAPIName: "IsEligible__c",
		Condition:    "", // no condition — always runs
		ValueFormula: "IF($Permission.SpecialAccess, true, false)",
		Priority:     5,
	}
	ctx, resolver := makeResolverCtx(row)
	record := models.SObject{}

	err := resolver.Apply(ctx, record, "Lead", map[string]interface{}{}, true /* isSuperUser */)
	if err != nil {
		t.Fatalf("Apply() returned unexpected error: %v", err)
	}
	got, ok := record["IsEligible__c"]
	if !ok {
		t.Fatal("Apply(): IsEligible__c was not written")
	}
	if got != true {
		t.Errorf("Apply(): IsEligible__c = %v; want true for super-user $Permission.SpecialAccess", got)
	}
}

// TestFieldDefaultResolver_SuperUser_NoPermissionRef verifies that rows with no
// $Permission reference are unaffected by the isSuperUser flag.
func TestFieldDefaultResolver_SuperUser_NoPermissionRef(t *testing.T) {
	row := seedrows.ActionFieldDefaultRow{
		TargetObject: "Account",
		FieldAPIName: "Rating",
		Condition:    "",
		ValueFormula: "'Hot'",
		Priority:     1,
	}
	ctx, resolver := makeResolverCtx(row)
	record := models.SObject{}

	err := resolver.Apply(ctx, record, "Account", map[string]interface{}{}, true /* isSuperUser */)
	if err != nil {
		t.Fatalf("Apply() returned unexpected error: %v", err)
	}
	got, ok := record["Rating"]
	if !ok {
		t.Fatal("Apply(): Rating was not written")
	}
	if got != "Hot" {
		t.Errorf("Apply(): Rating = %q; want %q", got, "Hot")
	}
}
