package catalogsystem

import (
	"strings"
	"testing"

	layoutbundlekeyv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/layoutbundlekeyv1"
	systemauthorityv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/systemlayoutbundleauthorityv1"
)

const (
	testCommand1 = systemauthorityv1.CommandID("01890f9e-7b2a-7000-8000-000000000001")
	testCommand2 = systemauthorityv1.CommandID("01890f9e-7b2a-7000-8000-000000000002")
	testCommand3 = systemauthorityv1.CommandID("01890f9e-7b2a-7000-8000-000000000003")
)

var testPrincipal = authenticatedPrincipal{
	PrincipalID: "controlplane-system-slot-writer",
	AuditDigest: testDigest("a"),
}

func testDigest(character string) string {
	return "sha256:" + strings.Repeat(character, 64)
}

func testBundleKey(character string) systemauthorityv1.BundleKey {
	return systemauthorityv1.BundleKey{
		BundleKeyVersion:   layoutbundlekeyv1.BundleKeyVersion,
		SlotOwnerKind:      layoutbundlekeyv1.SlotOwnerKindSystem,
		SlotOwnerNamespace: layoutbundlekeyv1.SystemSlotOwnerNamespace,
		LocalComponentKey: layoutbundlekeyv1.LocalComponentKey(
			"key256:" + strings.Repeat(character, 64),
		),
	}
}

func testSlotValue(
	character string,
	state systemauthorityv1.SlotState,
) systemauthorityv1.SystemLayoutBundleSlotV1 {
	return systemauthorityv1.SystemLayoutBundleSlotV1{
		ValueVersion: systemauthorityv1.SlotValueVersion,
		BundleKey:    testBundleKey(character),
		State:        state,
	}
}

func testCreateRequest(
	character string,
) systemauthorityv1.SystemLayoutBundleSlotCommandRequest {
	return systemauthorityv1.SystemLayoutBundleSlotCommandRequest{
		Operation:        systemauthorityv1.OperationCreate,
		TargetBundleKey:  testBundleKey(character),
		DesiredSlotValue: testSlotValue(character, systemauthorityv1.SlotStateActive),
		ExpectedPrior: systemauthorityv1.ExpectedPrior{
			Variant: systemauthorityv1.ExpectedPriorAbsent,
		},
	}
}

func testRetireRequest(
	t *testing.T,
	character string,
) systemauthorityv1.SystemLayoutBundleSlotCommandRequest {
	t.Helper()
	return systemauthorityv1.SystemLayoutBundleSlotCommandRequest{
		Operation:        systemauthorityv1.OperationRetire,
		TargetBundleKey:  testBundleKey(character),
		DesiredSlotValue: testSlotValue(character, systemauthorityv1.SlotStateTombstone),
		ExpectedPrior: systemauthorityv1.ExpectedPrior{
			Variant: systemauthorityv1.ExpectedPriorExact,
			SlotValueDigest: mustSlotDigest(
				t,
				testSlotValue(character, systemauthorityv1.SlotStateActive),
			),
		},
	}
}

func mustSlotDigest(
	t *testing.T,
	value systemauthorityv1.SystemLayoutBundleSlotV1,
) string {
	t.Helper()
	digest, err := systemauthorityv1.SlotValueDigest(value)
	if err != nil {
		t.Fatal(err)
	}
	return digest
}

func mustRequestDigest(
	t *testing.T,
	request systemauthorityv1.SystemLayoutBundleSlotCommandRequest,
) string {
	t.Helper()
	digest, err := systemauthorityv1.CommandRequestDigest(request)
	if err != nil {
		t.Fatal(err)
	}
	return digest
}
