// White-box (package packs) reconstruction-fidelity test for the
// search_all_default_fields presentation kind in the SF-skin migration.
//
// IMPORTANT CORPUS NOTE: the salesforce-crm-standard manifest declares NO
// search_all_default_fields component (verified: pack.json has zero entries of
// this kind), so — unlike the other three kinds — there is no real manifest to
// drive an internal-vs-routed deep-compare against the live SF pack, and a
// fired-counter guard on the SF build is impossible. The engine sink is still
// implemented and routable for completeness/future packs.
//
// To still PROVE reconstruction fidelity, this test exercises the exact two code
// paths the route depends on against a synthetic payload: the internal builder
// (newSourceBackedSearchAllDefaultFieldsComponent, which parses raw bytes) and the
// engine sink's shared constructor fed the typed cp declarations the provider
// would emit (newSearchAllDefaultFieldsManagedComponentFromDeclarations). cp.Search
// AllDefaultFieldsDeclaration is field-for-field 1:1 with the internal
// searchmetadata type, so the two components must be byte-identical on payload and
// DeepEqual on the parsed projection. A mutation sub-test corrupts one declared
// Field and asserts the projection deep-compare bites.
package packs

import (
	"encoding/json"
	"reflect"
	"testing"

	cp "github.com/pingcap-inc/nexuscrm-contract/pkg/controlplane"
	"github.com/nexuscrm/shared/pkg/searchmetadata"
)

func searchAllDefaultFieldsSyntheticPayload(t *testing.T) []byte {
	t.Helper()
	payload, err := json.Marshal([]searchmetadata.SearchAllDefaultFieldsDeclaration{
		{ObjectAPIName: "Account", Fields: []string{"Name", "AccountNumber"}},
		{ObjectAPIName: "Contact", Fields: []string{"Name", "Email"}},
	})
	if err != nil {
		t.Fatalf("marshal synthetic payload: %v", err)
	}
	return payload
}

// declsFromSearchAllPayloadForTest mirrors the provider's buildSearchAllDefaultFields:
// unmarshal req.Payload into []cp.SearchAllDefaultFieldsDeclaration.
func declsFromSearchAllPayloadForTest(t *testing.T, payload []byte) []cp.SearchAllDefaultFieldsDeclaration {
	t.Helper()
	var decls []cp.SearchAllDefaultFieldsDeclaration
	if err := json.Unmarshal(payload, &decls); err != nil {
		t.Fatalf("unmarshal cp decls: %v", err)
	}
	return decls
}

func TestExternalSearchAllDefaultFieldsRouteReconstruction(t *testing.T) {
	payload := searchAllDefaultFieldsSyntheticPayload(t)
	component := ManifestComponent{
		Kind:          ComponentKindSearchAllDefaultFields,
		BusinessKey:   "salesforce-crm-standard",
		Manageability: ManageabilityLocked,
		Path:          "search/search_all_default_fields.json",
	}

	// Control: internal builder parses the raw payload.
	controlComp, _, err := newSourceBackedSearchAllDefaultFieldsComponent("salesforce-crm-standard", component, payload)
	if err != nil {
		t.Fatalf("internal builder: %v", err)
	}

	// Routed: map the typed cp declarations the provider emits into the internal
	// type (exactly as the engine sink does), validate, and build via the shared
	// constructor.
	decls := declsFromSearchAllPayloadForTest(t, payload)
	mapped := make([]searchmetadata.SearchAllDefaultFieldsDeclaration, len(decls))
	for i, d := range decls {
		mapped[i] = searchmetadata.SearchAllDefaultFieldsDeclaration{
			ObjectAPIName: d.ObjectAPIName,
			Fields:        append([]string(nil), d.Fields...),
		}
	}
	if err := searchmetadata.ValidatePackSearchAllDefaultFields(mapped); err != nil {
		t.Fatalf("validate mapped decls: %v", err)
	}
	routedComp := newSearchAllDefaultFieldsManagedComponentFromDeclarations("salesforce-crm-standard", component, payload, mapped)

	if mismatch := assertRouteComponentsEqual(t, controlComp, routedComp); mismatch != "" {
		t.Errorf("DRIFT: external search_all_default_fields reconstruction is lossy.\n%s", mismatch)
	}

	// Guard: the projection MUST carry parsed field content.
	proj, err := controlComp.ExpectedProjection()
	if err != nil {
		t.Fatalf("control projection: %v", err)
	}
	fields, ok := proj.([]searchmetadata.SearchAllDefaultFieldsDeclaration)
	if !ok {
		t.Fatalf("ExpectedProjection type %T, want []searchmetadata.SearchAllDefaultFieldsDeclaration", proj)
	}
	if len(fields) == 0 {
		t.Fatalf("projection is empty; nothing to compare")
	}
}

// TestExternalSearchAllDefaultFieldsRouteMutationCaught corrupts one declared
// Field and asserts the projection deep-compare FAILS, proving the parsed-content
// surface is exercised (not just the raw payload bytes).
func TestExternalSearchAllDefaultFieldsRouteMutationCaught(t *testing.T) {
	payload := searchAllDefaultFieldsSyntheticPayload(t)
	component := ManifestComponent{
		Kind:          ComponentKindSearchAllDefaultFields,
		BusinessKey:   "salesforce-crm-standard",
		Manageability: ManageabilityLocked,
		Path:          "search/search_all_default_fields.json",
	}

	controlComp, _, err := newSourceBackedSearchAllDefaultFieldsComponent("salesforce-crm-standard", component, payload)
	if err != nil {
		t.Fatalf("internal builder: %v", err)
	}

	decls := declsFromSearchAllPayloadForTest(t, payload)
	mapped := make([]searchmetadata.SearchAllDefaultFieldsDeclaration, len(decls))
	for i, d := range decls {
		mapped[i] = searchmetadata.SearchAllDefaultFieldsDeclaration{
			ObjectAPIName: d.ObjectAPIName,
			Fields:        append([]string(nil), d.Fields...),
		}
	}
	// Corrupt one parsed field (raw payload stays untouched).
	mapped[0].Fields[0] = mapped[0].Fields[0] + "_corrupted"
	routedComp := newSearchAllDefaultFieldsManagedComponentFromDeclarations("salesforce-crm-standard", component, payload, mapped)

	cProj, err := controlComp.ExpectedProjection()
	if err != nil {
		t.Fatalf("control projection: %v", err)
	}
	rProj, err := routedComp.ExpectedProjection()
	if err != nil {
		t.Fatalf("routed projection: %v", err)
	}
	if reflect.DeepEqual(cProj, rProj) {
		t.Fatalf("MUTATION NOT CAUGHT: a corrupted Field produced no projection drift; the content surface is blind")
	}
}
