package packs

import (
	"strings"
	"testing"
)

// TestCheckStrictChildCopyInConfig pins the Phase 2b closure for the
// retired action-level workflow.childCopy surface. After Phase 2
// removed the runtime executor, accepting any non-empty
// workflow.childCopy at authoring time would make this a fake
// metadata surface (writer accepts / runtime ignores). The primitive
// lives in pkg/actionvalidate and is wrapped here for the packs
// import-cycle workaround; the contract it enforces is the same.
func TestCheckStrictChildCopyInConfig(t *testing.T) {
	t.Run("nil config passes", func(t *testing.T) {
		if err := CheckStrictChildCopyInConfig("X", nil); err != nil {
			t.Fatalf("nil config should pass, got %v", err)
		}
	})
	t.Run("no workflow passes", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("X", map[string]interface{}{"lookupField": "AccountId"})
		if err != nil {
			t.Fatalf("config without workflow should pass, got %v", err)
		}
	})
	t.Run("workflow without childCopy passes", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("X", map[string]interface{}{
			"workflow": map[string]interface{}{
				"fieldMappings": map[string]interface{}{"Name": "Name"},
			},
		})
		if err != nil {
			t.Fatalf("workflow without childCopy should pass, got %v", err)
		}
	})
	t.Run("empty childCopy array passes (explicit clear lever)", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("X", map[string]interface{}{
			"workflow": map[string]interface{}{
				"childCopy": []interface{}{},
			},
		})
		if err != nil {
			t.Fatalf("empty childCopy array should pass, got %v", err)
		}
	})
	t.Run("clean childCopy entry REJECTED — surface is retired", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("CreateQuote", map[string]interface{}{
			"workflow": map[string]interface{}{
				"childCopy": []interface{}{
					map[string]interface{}{
						"sourceObject":      "OpportunityLineItem",
						"sourceLookupField": "OpportunityId",
						"targetObject":      "quote_product__c",
						"targetLookupField": "Quote__c",
						"fieldMappings":     map[string]interface{}{"Product__c": "Product2Id"},
					},
				},
			},
		})
		if err == nil {
			t.Fatal("clean childCopy must be rejected — surface is retired")
		}
		if !strings.Contains(err.Error(), "retired") ||
			!strings.Contains(err.Error(), "CreateQuote") ||
			!strings.Contains(err.Error(), "_System_Object.ChildCloneRules") {
			t.Fatalf("error should name surface as retired, name action, and point at replacement: %v", err)
		}
	})
	t.Run("entry with sourceIdField REJECTED (broader check subsumes narrow one)", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("CreateOrder", map[string]interface{}{
			"workflow": map[string]interface{}{
				"childCopy": []interface{}{
					map[string]interface{}{
						"sourceObject":      "quote_product__c",
						"sourceLookupField": "Quote__c",
						"sourceIdField":     "Quote_Product__c",
						"targetObject":      "order_product__c",
						"targetLookupField": "Order__c",
					},
				},
			},
		})
		if err == nil {
			t.Fatal("childCopy with sourceIdField must hard-fail")
		}
		if !strings.Contains(err.Error(), "CreateOrder") ||
			!strings.Contains(err.Error(), "retired") {
			t.Fatalf("error should name the action and the retired surface: %v", err)
		}
	})
	t.Run("multiple entries REJECTED — error surfaces count", func(t *testing.T) {
		err := CheckStrictChildCopyInConfig("SomeAction", map[string]interface{}{
			"workflow": map[string]interface{}{
				"childCopy": []interface{}{
					map[string]interface{}{"sourceObject": "A", "targetObject": "B"},
					map[string]interface{}{"sourceObject": "C", "targetObject": "D"},
				},
			},
		})
		if err == nil {
			t.Fatal("expected rejection on multi-entry childCopy")
		}
		if !strings.Contains(err.Error(), "2 entrie") {
			t.Fatalf("error should name the entry count: %v", err)
		}
	})
}
