package controlplane

import (
	"context"
	"strings"
	"testing"

	"github.com/pingcap-inc/nexuscrm-controlplane/packs"
)

func TestInstallPackPreflightOverridesSeparateDesiredAndRuntimeContexts(t *testing.T) {
	legacy := testApplyAllSourceRevisionTarget(t, "peer", "0.9.0", "official_repo", "peer", "legacy")
	desired := testApplyAllSourceRevisionTarget(t, "peer", "2.0.0", "official_repo", "peer", "target")
	runtimeEffective := testApplyAllSourceRevisionTarget(t, "peer", "1.0.0", "official_repo", "peer", "current")
	overrides := &installPackPreflightOverrides{
		plannedDesiredPacks:   testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{"peer": desired}),
		runtimeEffectivePacks: testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{"peer": runtimeEffective}),
		activeDriftedPacks:    map[string]*packs.SourceBackedPack{"peer": legacy},
	}

	if got := desiredPackOverridesFromPreflight(overrides)["peer"]; got != desired {
		t.Fatalf("desired override = %p, want %p", got, desired)
	}
	if got, ok := lookupDesiredPackOverride(overrides, "  PEER "); !ok || got != desired {
		t.Fatalf("desired lookup = (%p, %t), want (%p, true)", got, ok, desired)
	}
	if got := runtimeEffectivePackOverridesFromPreflight(overrides)["peer"]; got != runtimeEffective {
		t.Fatalf("runtime-effective override = %p, want %p", got, runtimeEffective)
	}
	if got := runtimeDeclarationOverridesFromPreflight(overrides)["peer"]; got != runtimeEffective {
		t.Fatalf("runtime declaration override = %p, want %p", got, runtimeEffective)
	}
	if got := runtimeDeclarationOverridesFromPreflightExcludingPack(overrides, "other")["peer"]; got != runtimeEffective {
		t.Fatalf("runtime declaration override excluding other = %p, want %p", got, runtimeEffective)
	}
	if got := runtimeEffectiveDeclarationPacksFromPreflight(overrides); len(got) != 1 || got[0] != runtimeEffective {
		t.Fatalf("runtime declaration packs = %#v, want runtime-effective peer", got)
	}
}

func TestInstallPackPreflightOverridesSeparateRuntimeProjectionCompatibility(t *testing.T) {
	desired := testApplyAllSourceRevisionTarget(t, "peer", "2.0.0", "official_repo", "peer", "target")
	compatibility, err := (packs.PersistedRuntimeDeclarationJSON{
		ObjectSpecs: "[]", RelatedLists: "[]", SearchScope: "[]",
		SearchAllDefaultFields: "[]", FormulaFunctionBundles: "[]", StartupShallow: "[]",
	}).LoadPack("peer")
	if err != nil {
		t.Fatalf("load persisted runtime compatibility pack: %v", err)
	}
	overrides := &installPackPreflightOverrides{
		plannedDesiredPacks:   testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{"peer": desired}),
		runtimeEffectivePacks: testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{}),
		runtimeProjectionCompatibilityPacks: testInstallPackPreflightRuntimeDeclarationContext(
			t, map[string]packs.Pack{"peer": compatibility},
		),
	}

	if got := desiredPackOverridesFromPreflight(overrides)["peer"]; got != desired {
		t.Fatalf("desired override = %p, want %p", got, desired)
	}
	if got := runtimeEffectivePackOverridesFromPreflight(overrides); got == nil || len(got) != 0 {
		t.Fatalf("runtime-effective overrides = %#v, want exact empty context", got)
	}
	if got := runtimeDeclarationOverridesFromPreflight(overrides)["peer"]; got != compatibility {
		t.Fatalf("runtime declaration compatibility override = %p, want %p", got, compatibility)
	}
	if got := runtimeEffectiveDeclarationPacksFromPreflight(overrides); len(got) != 1 || got[0] != compatibility {
		t.Fatalf("runtime declaration packs = %#v, want compatibility peer", got)
	}
}

func TestInstallPackPreflightAttributionPeerContextPreservesExactEmptyOwnership(t *testing.T) {
	context, err := newInstallPackPreflightAttributionPeerContext(map[string][]string{
		"Peer-Pack":  {"Account", "Contact"},
		"empty-pack": {},
	})
	if err != nil {
		t.Fatalf("new attribution peer context: %v", err)
	}
	overrides := &installPackPreflightOverrides{activeGenerationAttributionPeers: context}
	peers := activeGenerationAttributionPeersFromPreflight(overrides)
	if peers == nil {
		t.Fatal("active-generation attribution peer context = nil")
	}
	objects, ok := peers.lookup("peer-pack")
	if !ok || len(objects) != 2 || objects[0] != "Account" || objects[1] != "Contact" {
		t.Fatalf("peer-pack ownership = %#v, %v", objects, ok)
	}
	objects[0] = "mutated"
	again, ok := peers.lookup("PEER-PACK")
	if !ok || again[0] != "Account" {
		t.Fatalf("peer-pack ownership was not cloned: %#v, %v", again, ok)
	}
	empty, ok := peers.lookup("empty-pack")
	if !ok || len(empty) != 0 {
		t.Fatalf("empty-pack ownership = %#v, %v; want authoritative empty entry", empty, ok)
	}
	if _, ok := peers.lookup("missing-pack"); ok {
		t.Fatal("missing attribution peer unexpectedly resolved")
	}
}

func TestInstallPackPreflightOverridesLegacyFallback(t *testing.T) {
	legacy := testApplyAllSourceRevisionTarget(t, "peer", "1.0.0", "official_repo", "peer", "current")
	overrides := &installPackPreflightOverrides{
		activeDriftedPacks: map[string]*packs.SourceBackedPack{"peer": legacy},
	}

	if got := desiredPackOverridesFromPreflight(overrides)["peer"]; got != legacy {
		t.Fatalf("desired legacy fallback = %p, want %p", got, legacy)
	}
	if got := runtimeEffectivePackOverridesFromPreflight(overrides)["peer"]; got != legacy {
		t.Fatalf("runtime legacy fallback = %p, want %p", got, legacy)
	}
	if got, ok := lookupDesiredPackOverride(overrides, "peer"); !ok || got != legacy {
		t.Fatalf("desired legacy lookup = (%p, %t), want (%p, true)", got, ok, legacy)
	}
	if got := runtimeDeclarationOverridesFromPreflight(overrides)["peer"]; got != legacy {
		t.Fatalf("runtime legacy declaration = %p, want %p", got, legacy)
	}
}

func TestInstallPackPreflightOverridesExplicitEmptyContextsSuppressLegacyFallback(t *testing.T) {
	legacy := testApplyAllSourceRevisionTarget(t, "peer", "1.0.0", "official_repo", "peer", "current")
	empty := testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{})
	legacyMap := map[string]*packs.SourceBackedPack{"peer": legacy}

	desiredEmpty := &installPackPreflightOverrides{
		plannedDesiredPacks: empty,
		activeDriftedPacks:  legacyMap,
	}
	if got := desiredPackOverridesFromPreflight(desiredEmpty); got == nil || len(got) != 0 {
		t.Fatalf("explicit empty desired = %#v, want non-nil empty", got)
	}
	if got := runtimeEffectivePackOverridesFromPreflight(desiredEmpty)["peer"]; got != legacy {
		t.Fatalf("runtime fallback = %p, want legacy %p", got, legacy)
	}

	runtimeEmpty := &installPackPreflightOverrides{
		runtimeEffectivePacks: empty,
		activeDriftedPacks:    legacyMap,
	}
	if got := runtimeEffectivePackOverridesFromPreflight(runtimeEmpty); got == nil || len(got) != 0 {
		t.Fatalf("explicit empty runtime = %#v, want non-nil empty", got)
	}
	if got := desiredPackOverridesFromPreflight(runtimeEmpty)["peer"]; got != legacy {
		t.Fatalf("desired fallback = %p, want legacy %p", got, legacy)
	}
}

func TestNewInstallPackPreflightPackContextCanonicalizesAndRejectsMalformedEntries(t *testing.T) {
	peer := testApplyAllSourceRevisionTarget(t, "peer", "1.0.0", "official_repo", "peer", "current")
	canonical, err := newInstallPackPreflightPackContext(map[string]*packs.SourceBackedPack{"  PEER ": peer})
	if err != nil {
		t.Fatalf("canonical context: %v", err)
	}
	if len(canonical.byName) != 1 || canonical.byName["peer"] != peer {
		t.Fatalf("canonical context = %#v, want lowercase peer", canonical.byName)
	}

	tests := []struct {
		name    string
		raw     map[string]*packs.SourceBackedPack
		wantErr string
	}{
		{name: "empty key", raw: map[string]*packs.SourceBackedPack{" ": peer}, wantErr: "empty key"},
		{name: "nil pack", raw: map[string]*packs.SourceBackedPack{"peer": nil}, wantErr: "is nil"},
		{name: "key name mismatch", raw: map[string]*packs.SourceBackedPack{"other": peer}, wantErr: "does not match"},
		{
			name: "duplicate canonical key",
			raw: map[string]*packs.SourceBackedPack{
				"peer":   peer,
				" PEER ": peer,
			},
			wantErr: "duplicates canonical name",
		},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			_, err := newInstallPackPreflightPackContext(test.raw)
			if err == nil || !strings.Contains(err.Error(), test.wantErr) {
				t.Fatalf("context error = %v, want containing %q", err, test.wantErr)
			}
		})
	}
}

func TestInstallPackPreflightPackContextsDoNotLeakMutableMaps(t *testing.T) {
	desired := testApplyAllSourceRevisionTarget(t, "desired", "2.0.0", "official_repo", "desired", "target")
	runtimeEffective := testApplyAllSourceRevisionTarget(t, "runtime", "1.0.0", "official_repo", "runtime", "current")
	rawDesired := map[string]*packs.SourceBackedPack{"desired": desired}
	rawRuntime := map[string]*packs.SourceBackedPack{"runtime": runtimeEffective}
	overrides := &installPackPreflightOverrides{
		plannedDesiredPacks:   testInstallPackPreflightPackContext(t, rawDesired),
		runtimeEffectivePacks: testInstallPackPreflightPackContext(t, rawRuntime),
	}

	delete(rawDesired, "desired")
	rawRuntime["runtime"] = desired
	desiredRead := desiredPackOverridesFromPreflight(overrides)
	runtimeRead := runtimeEffectivePackOverridesFromPreflight(overrides)
	delete(desiredRead, "desired")
	runtimeRead["runtime"] = desired

	if got := desiredPackOverridesFromPreflight(overrides); len(got) != 1 || got["desired"] != desired {
		t.Fatalf("desired context after caller mutation = %#v, want original desired pack", got)
	}
	if got := runtimeEffectivePackOverridesFromPreflight(overrides); len(got) != 1 || got["runtime"] != runtimeEffective {
		t.Fatalf("runtime context after caller mutation = %#v, want original runtime pack", got)
	}
}

func TestWithRuntimeEffectivePeerDeclarationOverridesExactEmptyMasksInherited(t *testing.T) {
	peer := testApplyAllSourceRevisionTarget(t, "peer", "1.0.0", "official_repo", "peer", "current")
	inherited := packs.WithPeerDeclarationOverrides(context.Background(), map[string]*packs.SourceBackedPack{"peer": peer})
	if got, ok := packs.PeerDeclarationOverrideFromContext(inherited, "peer"); !ok || got != peer {
		t.Fatalf("inherited override = (%p, %t), want (%p, true)", got, ok, peer)
	}

	explicitEmpty := withRuntimeEffectivePeerDeclarationOverrides(inherited, &installPackPreflightOverrides{
		runtimeEffectivePacks: testInstallPackPreflightPackContext(t, map[string]*packs.SourceBackedPack{}),
	})
	if got, ok := packs.PeerDeclarationOverrideFromContext(explicitEmpty, "peer"); ok || got != nil {
		t.Fatalf("exact empty override = (%p, %t), want (nil, false)", got, ok)
	}

	legacy := withRuntimeEffectivePeerDeclarationOverrides(inherited, &installPackPreflightOverrides{})
	if got, ok := packs.PeerDeclarationOverrideFromContext(legacy, "peer"); !ok || got != peer {
		t.Fatalf("legacy empty fallback = (%p, %t), want inherited (%p, true)", got, ok, peer)
	}
}

func testInstallPackPreflightRuntimeDeclarationContext(t *testing.T, raw map[string]packs.Pack) *installPackPreflightRuntimeDeclarationContext {
	t.Helper()
	packContext, err := newInstallPackPreflightRuntimeDeclarationContext(raw)
	if err != nil {
		t.Fatalf("new install-pack runtime declaration context: %v", err)
	}
	return packContext
}

func testInstallPackPreflightPackContext(t *testing.T, raw map[string]*packs.SourceBackedPack) *installPackPreflightPackContext {
	t.Helper()
	packContext, err := newInstallPackPreflightPackContext(raw)
	if err != nil {
		t.Fatalf("new install-pack preflight pack context: %v", err)
	}
	return packContext
}
