package sfcrmappservice

import (
	"encoding/json"
	permissionsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/effectivepermissionsv1"
	"os"
	"testing"
)

// Use authored product metadata: a navigation type alone does not describe
// whether the configured action creates related rows.
func TestConfiguredQuickActionCreationAuthority(t *testing.T) {
	raw, err := os.ReadFile("../../salesforce-crm-standard/actions/ui_actions.json")
	if err != nil {
		t.Fatal(err)
	}
	var authored []effectiveObjectActionSpec
	if err := json.Unmarshal(raw, &authored); err != nil {
		t.Fatal(err)
	}
	var product effectiveObjectActionSpec
	for _, a := range authored {
		if a.Name == "AddProducts" {
			product = a
		}
	}
	if product.Config == nil {
		t.Fatal("official AddProducts missing")
	}
	for _, tc := range []struct {
		name                      string
		objectCreate, fieldCreate bool
		mutate                    string
		want                      bool
	}{
		{name: "official_allowed", objectCreate: true, fieldCreate: true, want: true},
		{name: "official_field_denied", objectCreate: true},
		{name: "renamed_field_denied", objectCreate: true, mutate: "rename"},
		{name: "renamed_object_denied", fieldCreate: true, mutate: "rename"},
		{name: "renamed_allowed", objectCreate: true, fieldCreate: true, mutate: "rename", want: true},
		{name: "malformed_picker", objectCreate: true, fieldCreate: true, mutate: "malformed"},
		{name: "missing_batch", objectCreate: true, fieldCreate: true, mutate: "missing_batch"},
		{name: "conflicting_target", objectCreate: true, fieldCreate: true, mutate: "target"},
		{name: "conflicting_navigation_target", objectCreate: true, fieldCreate: true, mutate: "navigation_target"},
		{name: "conflicting_lookup", objectCreate: true, fieldCreate: true, mutate: "lookup"},
	} {
		t.Run(tc.name, func(t *testing.T) {
			encoded, _ := json.Marshal(product)
			var action effectiveObjectActionSpec
			if err := json.Unmarshal(encoded, &action); err != nil {
				t.Fatal(err)
			}
			picker := action.Config["productPicker"].(map[string]any)
			switch tc.mutate {
			case "rename":
				action.Name = "ConfiguredLineCreation"
			case "malformed":
				action.Config["productPicker"] = true
			case "missing_batch":
				delete(picker, "batchCreate")
			case "navigation_target":
				action.Config["targetObject"] = "Other"
			case "target":
				picker["batchCreate"].(map[string]any)["targetObject"] = "Other"
			case "lookup":
				picker["parentLookupField"] = "OtherId"
			}
			tableType := "standard_object"
			specs := map[string]searchObjectSpec{"opportunity": {APIName: "Opportunity", TableType: &tableType}, "opportunitylineitem": {APIName: "OpportunityLineItem", TableType: &tableType, Fields: []searchFieldSpec{{APIName: "OpportunityId", Createable: true}}}}
			perms := permissionsemantic.Response{ObjectPermissions: []permissionsemantic.ObjectPermission{{ResourceType: "Opportunity", CanRead: true}, {ResourceType: "OpportunityLineItem", CanRead: true, CanCreate: tc.objectCreate}}, FieldPermissions: []permissionsemantic.FieldPermission{{ResourceType: "OpportunityLineItem", FieldName: "OpportunityId", CanRead: true, CanCreate: tc.fieldCreate}}}
			got := projectQuickActions("Opportunity", []effectiveObjectActionSpec{action}, specs, perms)
			if (len(got) == 1) != tc.want {
				t.Fatalf("action visible=%v want=%v", len(got) == 1, tc.want)
			}
		})
	}
}
