package permissions

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"reflect"
	"slices"
	"sort"
	"strings"

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

type customPermissionLifecycleAction string

const (
	customPermissionLifecycleCreate customPermissionLifecycleAction = "create"
	customPermissionLifecycleSync   customPermissionLifecycleAction = "sync"
	customPermissionLifecycleNoop   customPermissionLifecycleAction = "noop"
)

type customPermissionOpaquePlan struct {
	Scope       cp.ComponentManagedScope        `json:"scope"`
	PackName    string                          `json:"pack_name"`
	BusinessKey string                          `json:"business_key,omitempty"`
	Action      customPermissionLifecycleAction `json:"action,omitempty"`
	Stale       []string                        `json:"stale,omitempty"`
}

type customPermissionSetProjection struct {
	BusinessKeys []string `json:"businessKeys"`
}

type customPermissionState struct {
	ID         string
	Projection customPermissionProjection
}

// customPermissionPreservedProjection is the verification surface for an
// administrator-customized row. Pack apply preserves administrator-owned
// content, but identity, ownership, and live-state invariants remain strict.
type customPermissionPreservedProjection struct {
	Present    bool   `json:"present"`
	APIName    string `json:"apiName"`
	OwnerPack  string `json:"ownerPack"`
	Customized bool   `json:"customized"`
	Active     bool   `json:"active"`
	Deleted    bool   `json:"deleted"`
}

func planCustomPermission(
	ctx context.Context,
	scope cp.ComponentManagedScope,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedPlan, error) {
	if store == nil {
		return cp.ComponentManagedPlan{}, fmt.Errorf("custom permission lifecycle plan store is required")
	}
	if err := request.Validate(scope); err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	switch scope {
	case cp.ComponentManagedScopeItem:
		return planCustomPermissionItem(ctx, request, store)
	case cp.ComponentManagedScopeSet:
		return planCustomPermissionSet(ctx, request, store, references)
	default:
		return cp.ComponentManagedPlan{}, fmt.Errorf("custom permission lifecycle scope %q is unsupported", scope)
	}
}

func planCustomPermissionItem(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
) (cp.ComponentManagedPlan, error) {
	expected, err := customPermissionExpectedRequest(*request.Item)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	state, err := readCustomPermissionState(ctx, store, expected.APIName, false)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	action, err := customPermissionItemAction(expected, state)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	delta := boolInt(action != customPermissionLifecycleNoop)
	opaque, err := json.Marshal(customPermissionOpaquePlan{
		Scope:       cp.ComponentManagedScopeItem,
		PackName:    request.Item.PackName,
		BusinessKey: request.Item.Component.BusinessKey,
		Action:      action,
	})
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	target, err := CustomPermissionManagedTarget(expected.APIName)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	return cp.NewComponentManagedPlan(cp.ComponentManagedPlanSpec{
		Targets: []cp.ComponentManagedTarget{
			target,
			customPermissionManagedSetTarget(request.Item.PackName),
		},
		RequiredCapabilities: customPermissionItemCapabilities(),
		Estimate: cp.ComponentManagedUsage{
			CurrentItems:       boolInt(state != nil),
			DesiredItems:       1,
			DeltaRows:          delta,
			MutationStatements: delta,
			EffectCalls:        delta,
		},
		Effects: []cp.ComponentManagedEffectRequirement{{
			Class: PermissionSetDefinitionPermissionStateEffectClass,
			Triggers: []cp.ComponentManagedMutationDisposition{
				cp.ComponentManagedMutationDesiredProjectionStaged,
			},
		}},
		ProjectionIdentity: customPermissionItemProjectionIdentity(*request.Item),
		OpaquePlan:         opaque,
	})
}

func planCustomPermissionSet(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedPlan, error) {
	if err := validateCustomPermissionSetRequest(*request.Set); err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	desired, err := customPermissionDesiredSet(request.DesiredBusinessKeys)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	states, err := readCustomPermissionOwnerSet(ctx, store, request.Set.PackName, false)
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	targets := []cp.ComponentManagedTarget{customPermissionManagedSetTarget(request.Set.PackName)}
	for _, key := range request.DesiredBusinessKeys {
		target, targetErr := CustomPermissionManagedTarget(key)
		if targetErr != nil {
			return cp.ComponentManagedPlan{}, targetErr
		}
		targets = append(targets, target)
	}
	stale := make([]string, 0)
	for _, state := range states {
		target, targetErr := CustomPermissionManagedTarget(state.Projection.APIName)
		if targetErr != nil {
			return cp.ComponentManagedPlan{}, targetErr
		}
		targets = append(targets, target)
		// IsCustomized transfers field and lifecycle ownership to the
		// administrator. The exact pack set deliberately excludes those rows,
		// matching the controlplane's generic managed-set drift rule: a source
		// removal must not turn an administrator-owned row into a tombstone.
		if state.Projection.Customized {
			continue
		}
		if _, retained := desired[strings.ToLower(state.Projection.APIName)]; retained {
			continue
		}
		if err := rejectCustomPermissionRetirementReferences(ctx, store, state, references, false); err != nil {
			return cp.ComponentManagedPlan{}, err
		}
		if state.Projection.Active || !state.Projection.Deleted {
			stale = append(stale, state.Projection.APIName)
		}
	}
	stale = customPermissionCollationOrderedNames(stale)
	opaque, err := json.Marshal(customPermissionOpaquePlan{
		Scope: cp.ComponentManagedScopeSet, PackName: request.Set.PackName, Stale: stale,
	})
	if err != nil {
		return cp.ComponentManagedPlan{}, err
	}
	delta := len(stale)
	return cp.NewComponentManagedPlan(cp.ComponentManagedPlanSpec{
		Targets:              targets,
		RequiredCapabilities: customPermissionSetCapabilities(),
		Estimate: cp.ComponentManagedUsage{
			CurrentItems:       len(states),
			DesiredItems:       len(request.DesiredBusinessKeys),
			DeltaRows:          delta,
			MutationStatements: delta,
			EffectCalls:        boolInt(delta != 0),
		},
		Effects: []cp.ComponentManagedEffectRequirement{{
			Class: PermissionSetDefinitionPermissionStateEffectClass,
			Triggers: []cp.ComponentManagedMutationDisposition{
				cp.ComponentManagedMutationDesiredProjectionStaged,
			},
		}},
		ProjectionIdentity: customPermissionSetProjectionIdentity(*request.Set),
		OpaquePlan:         opaque,
	})
}

func mutateCustomPermission(
	ctx context.Context,
	scope cp.ComponentManagedScope,
	request cp.ComponentManagedLifecycleRequest,
	plan cp.ComponentManagedPlan,
	store cp.ComponentManagedMutationStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedMutationResult, error) {
	if store == nil {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission lifecycle mutation store is required")
	}
	if err := request.Validate(scope); err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	if err := plan.Validate(); err != nil {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission lifecycle plan: %w", err)
	}
	var opaque customPermissionOpaquePlan
	if err := json.Unmarshal(plan.OpaquePlan(), &opaque); err != nil {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("decode custom permission lifecycle plan: %w", err)
	}
	if opaque.Scope != scope {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf(
			"custom permission lifecycle plan scope %q does not match %q",
			opaque.Scope,
			scope,
		)
	}
	switch scope {
	case cp.ComponentManagedScopeItem:
		return mutateCustomPermissionItem(ctx, request, opaque, store)
	case cp.ComponentManagedScopeSet:
		return mutateCustomPermissionSet(ctx, request, opaque, store, references)
	default:
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission lifecycle scope %q is unsupported", scope)
	}
}

func mutateCustomPermissionItem(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	opaque customPermissionOpaquePlan,
	store cp.ComponentManagedMutationStore,
) (cp.ComponentManagedMutationResult, error) {
	if opaque.PackName != request.Item.PackName || opaque.BusinessKey != request.Item.Component.BusinessKey {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission item plan identity does not match request")
	}
	expected, err := customPermissionExpectedRequest(*request.Item)
	if err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	state, err := readCustomPermissionState(ctx, store, expected.APIName, true)
	if err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	action, err := customPermissionItemAction(expected, state)
	if err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	if action != opaque.Action {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf(
			"custom permission %s changed after planning: action is %q, planned %q",
			expected.APIName,
			action,
			opaque.Action,
		)
	}
	switch action {
	case customPermissionLifecycleNoop:
		return cp.ComponentManagedMutationResult{Disposition: cp.ComponentManagedMutationNoChange}, nil
	case customPermissionLifecycleCreate:
		id, idErr := store.NewID()
		if idErr != nil {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("allocate custom permission ID: %w", idErr)
		}
		affected, insertErr := store.InsertRows(ctx, cp.ComponentManagedInsertBatch{
			Table: "_System_CustomPermission",
			Rows: []cp.ComponentManagedInsertRow{{
				LogicalKey: cp.ComponentRow{"ApiName": expected.APIName},
				Values:     customPermissionDesiredRow(id, expected),
			}},
			CurrentTimestampColumns: []string{"CreatedDate", "LastModifiedDate"},
		})
		if insertErr != nil {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("insert custom permission %s: %w", expected.APIName, insertErr)
		}
		if affected != 1 {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("insert custom permission %s affected %d rows, want one", expected.APIName, affected)
		}
	case customPermissionLifecycleSync:
		values := customPermissionDesiredRow(state.ID, expected)
		delete(values, "Id")
		affected, updateErr := store.UpdateRows(ctx, cp.ComponentManagedUpdate{
			Table:                   "_System_CustomPermission",
			Match:                   cp.ComponentRow{"Id": state.ID},
			Values:                  values,
			CurrentTimestampColumns: []string{"LastModifiedDate"},
			MaximumAffectedRows:     1,
		})
		if updateErr != nil {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("update custom permission %s: %w", expected.APIName, updateErr)
		}
		if affected != 1 {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("update custom permission %s affected %d rows, want one", expected.APIName, affected)
		}
	default:
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission lifecycle action %q is unsupported", action)
	}
	return cp.ComponentManagedMutationResult{Disposition: cp.ComponentManagedMutationDesiredProjectionStaged}, nil
}

func mutateCustomPermissionSet(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	opaque customPermissionOpaquePlan,
	store cp.ComponentManagedMutationStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedMutationResult, error) {
	if opaque.PackName != request.Set.PackName {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission set plan identity does not match request")
	}
	if err := validateCustomPermissionSetRequest(*request.Set); err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	desired, err := customPermissionDesiredSet(request.DesiredBusinessKeys)
	if err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	states, err := readCustomPermissionOwnerSet(ctx, store, request.Set.PackName, true)
	if err != nil {
		return cp.ComponentManagedMutationResult{}, err
	}
	staleStates := make([]*customPermissionState, 0)
	stale := make([]string, 0)
	for _, state := range states {
		if state.Projection.Customized {
			continue
		}
		if _, retained := desired[strings.ToLower(state.Projection.APIName)]; retained {
			continue
		}
		if err := rejectCustomPermissionRetirementReferences(ctx, store, state, references, true); err != nil {
			return cp.ComponentManagedMutationResult{}, err
		}
		if state.Projection.Active || !state.Projection.Deleted {
			staleStates = append(staleStates, state)
			stale = append(stale, state.Projection.APIName)
		}
	}
	stale = customPermissionCollationOrderedNames(stale)
	sort.Slice(staleStates, func(i, j int) bool {
		return strings.ToLower(staleStates[i].Projection.APIName) < strings.ToLower(staleStates[j].Projection.APIName)
	})
	if !slices.Equal(stale, opaque.Stale) {
		return cp.ComponentManagedMutationResult{}, fmt.Errorf(
			"custom permission owner set changed after planning: stale keys %v, planned %v",
			stale,
			opaque.Stale,
		)
	}
	if len(staleStates) == 0 {
		return cp.ComponentManagedMutationResult{Disposition: cp.ComponentManagedMutationNoChange}, nil
	}
	for _, state := range staleStates {
		affected, updateErr := store.UpdateRows(ctx, cp.ComponentManagedUpdate{
			Table:                   "_System_CustomPermission",
			Match:                   cp.ComponentRow{"Id": state.ID},
			Values:                  cp.ComponentRow{"IsActive": false, "IsDeleted": true},
			CurrentTimestampColumns: []string{"LastModifiedDate"},
			MaximumAffectedRows:     1,
		})
		if updateErr != nil {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("retire custom permission %s: %w", state.Projection.APIName, updateErr)
		}
		if affected != 1 {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("retire custom permission %s affected %d rows, want one", state.Projection.APIName, affected)
		}
	}
	for _, state := range staleStates {
		if err := rejectCustomPermissionRetirementReferences(ctx, store, state, references, true); err != nil {
			return cp.ComponentManagedMutationResult{}, fmt.Errorf("custom permission %s gained a grant during retirement: %w", state.Projection.APIName, err)
		}
	}
	return cp.ComponentManagedMutationResult{Disposition: cp.ComponentManagedMutationDesiredProjectionStaged}, nil
}

func projectCustomPermission(
	ctx context.Context,
	scope cp.ComponentManagedScope,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedProjection, error) {
	if store == nil {
		return cp.ComponentManagedProjection{}, fmt.Errorf("custom permission lifecycle projection store is required")
	}
	if err := request.Validate(scope); err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	switch scope {
	case cp.ComponentManagedScopeItem:
		return projectCustomPermissionItem(ctx, request, store)
	case cp.ComponentManagedScopeSet:
		return projectCustomPermissionSet(ctx, request, store, references)
	default:
		return cp.ComponentManagedProjection{}, fmt.Errorf("custom permission lifecycle scope %q is unsupported", scope)
	}
}

func projectCustomPermissionItem(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
) (cp.ComponentManagedProjection, error) {
	expected, err := customPermissionExpectedRequest(*request.Item)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	state, err := readCustomPermissionState(ctx, store, expected.APIName, false)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	if err := validateCustomPermissionOwner(expected, state); err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	if state != nil && state.Projection.Customized {
		expectedPreserved := customPermissionPreservedProjection{
			Present:    true,
			APIName:    expected.APIName,
			OwnerPack:  expected.OwnerPack,
			Customized: true,
			Active:     true,
			Deleted:    false,
		}
		livePreserved := customPermissionPreservedProjection{
			Present:    state.Projection.Present,
			APIName:    state.Projection.APIName,
			OwnerPack:  state.Projection.OwnerPack,
			Customized: state.Projection.Customized,
			Active:     state.Projection.Active,
			Deleted:    state.Projection.Deleted,
		}
		expectedBytes, marshalErr := json.Marshal(expectedPreserved)
		if marshalErr != nil {
			return cp.ComponentManagedProjection{}, marshalErr
		}
		liveBytes, marshalErr := json.Marshal(livePreserved)
		if marshalErr != nil {
			return cp.ComponentManagedProjection{}, marshalErr
		}
		return cp.ComponentManagedProjection{
			Identity: customPermissionItemProjectionIdentity(*request.Item),
			Expected: expectedBytes,
			Live:     liveBytes,
		}, nil
	}
	live := customPermissionProjection{APIName: expected.APIName}
	if state != nil {
		live = state.Projection
	}
	expectedBytes, err := json.Marshal(expected)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	liveBytes, err := json.Marshal(live)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	return cp.ComponentManagedProjection{
		Identity: customPermissionItemProjectionIdentity(*request.Item),
		Expected: expectedBytes,
		Live:     liveBytes,
	}, nil
}

func projectCustomPermissionSet(
	ctx context.Context,
	request cp.ComponentManagedLifecycleRequest,
	store cp.ComponentManagedReadStore,
	references []customPermissionRetirementReferenceSurface,
) (cp.ComponentManagedProjection, error) {
	if err := validateCustomPermissionSetRequest(*request.Set); err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	desired, err := customPermissionDesiredSet(request.DesiredBusinessKeys)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	states, err := readCustomPermissionOwnerSet(ctx, store, request.Set.PackName, false)
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	live := make([]string, 0, len(states))
	for _, state := range states {
		_, retained := desired[strings.ToLower(state.Projection.APIName)]
		if state.Projection.Customized {
			if retained && state.Projection.Active && !state.Projection.Deleted {
				live = append(live, state.Projection.APIName)
			}
			continue
		}
		if retained && state.Projection.Active && !state.Projection.Deleted {
			live = append(live, state.Projection.APIName)
			continue
		}
		if retained {
			continue
		}
		if state.Projection.Active || !state.Projection.Deleted {
			live = append(live, state.Projection.APIName)
			continue
		}
		if err := rejectCustomPermissionRetirementReferences(ctx, store, state, references, false); err != nil {
			return cp.ComponentManagedProjection{}, err
		}
	}
	expectedBytes, err := json.Marshal(customPermissionSetProjection{
		BusinessKeys: customPermissionCollationOrderedNames(request.DesiredBusinessKeys),
	})
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	liveBytes, err := json.Marshal(customPermissionSetProjection{
		BusinessKeys: customPermissionCollationOrderedNames(live),
	})
	if err != nil {
		return cp.ComponentManagedProjection{}, err
	}
	return cp.ComponentManagedProjection{
		Identity: customPermissionSetProjectionIdentity(*request.Set),
		Expected: expectedBytes,
		Live:     liveBytes,
	}, nil
}

func customPermissionExpectedRequest(request cp.ComponentManagedRequest) (customPermissionProjection, error) {
	if err := validateCustomPermissionOwnerPack(request.PackName); err != nil {
		return customPermissionProjection{}, err
	}
	if request.SourceOwner != "" {
		return customPermissionProjection{}, fmt.Errorf("pack-owned custom permission must not declare source owner %q", request.SourceOwner)
	}
	if request.Component.Kind != customPermissionComponentKind {
		return customPermissionProjection{}, fmt.Errorf("component kind = %q, want %q", request.Component.Kind, customPermissionComponentKind)
	}
	if request.Component.Manageability != cp.ManageabilityLocked {
		return customPermissionProjection{}, fmt.Errorf("custom permission manageability must be locked")
	}
	if err := validateCustomPermissionIdentifier("API name", request.Component.BusinessKey, 255); err != nil {
		return customPermissionProjection{}, err
	}
	payload, err := decodeCustomPermissionPayload(request.Payload)
	if err != nil {
		return customPermissionProjection{}, err
	}
	canonical := customPermissionProjection{
		Present:     true,
		APIName:     request.Component.BusinessKey,
		OwnerPack:   request.PackName,
		Label:       payload.Label,
		Description: payload.Description,
		Active:      true,
	}
	canonicalBytes, err := json.Marshal(canonical)
	if err != nil {
		return customPermissionProjection{}, err
	}
	var expected customPermissionProjection
	if err := json.Unmarshal(request.ExpectedProjection, &expected); err != nil {
		return customPermissionProjection{}, fmt.Errorf("decode custom permission expected projection: %w", err)
	}
	if !bytes.Equal(request.ExpectedProjection, canonicalBytes) || !reflect.DeepEqual(expected, canonical) {
		return customPermissionProjection{}, fmt.Errorf("custom permission expected projection is not canonical for its source payload")
	}
	return canonical, nil
}

func readCustomPermissionState(
	ctx context.Context,
	store cp.ComponentManagedReadStore,
	apiName string,
	lock bool,
) (*customPermissionState, error) {
	query := permissionSetDefinitionQuery(
		"_System_CustomPermission",
		[]string{"Id", "ApiName", "Label", "Description", "IsActive", "IsDeleted", "IsCustomized", "OwnerPack"},
		cp.ComponentRow{"ApiName": apiName},
		customPermissionMaximumRowsPerRead,
	)
	query.LogicalKeyColumns = []string{"ApiName"}
	var rows []cp.ComponentRow
	var err error
	if lock {
		mutationStore, ok := store.(cp.ComponentManagedMutationStore)
		if !ok {
			return nil, fmt.Errorf("custom permission lock requires mutation store")
		}
		rows, err = mutationStore.LockRows(ctx, query)
	} else {
		rows, err = store.ReadRows(ctx, query)
	}
	if err != nil {
		return nil, fmt.Errorf("read custom permission %s: %w", apiName, err)
	}
	if len(rows) > 1 {
		return nil, fmt.Errorf("custom permission %s has %d rows under database collation", apiName, len(rows))
	}
	if len(rows) == 0 {
		return nil, nil
	}
	return decodeCustomPermissionState(rows[0])
}

func readCustomPermissionOwnerSet(
	ctx context.Context,
	store cp.ComponentManagedReadStore,
	ownerPack string,
	lock bool,
) ([]*customPermissionState, error) {
	query := cp.ComponentManagedRowQuery{
		Table: "_System_CustomPermission",
		Columns: []string{
			"Id", "ApiName", "Label", "Description", "IsActive", "IsDeleted", "IsCustomized", "OwnerPack",
		},
		Equal:             cp.ComponentRow{"OwnerPack": ownerPack},
		OrderBy:           []cp.ComponentManagedOrder{{Column: "ApiName", Direction: cp.ComponentManagedOrderAscending}},
		LogicalKeyColumns: []string{"ApiName"},
		MaximumRows:       customPermissionManagedMaximumRows,
	}
	var rows []cp.ComponentRow
	var err error
	if lock {
		mutationStore, ok := store.(cp.ComponentManagedMutationStore)
		if !ok {
			return nil, fmt.Errorf("custom permission owner-set lock requires mutation store")
		}
		rows, err = mutationStore.LockRows(ctx, query)
	} else {
		rows, err = store.ReadRows(ctx, query)
	}
	if err != nil {
		return nil, fmt.Errorf("read custom permission owner set %s: %w", ownerPack, err)
	}
	if len(rows) > customPermissionManagedMaximumRows {
		return nil, fmt.Errorf(
			"custom permission owner set %s contains %d rows; maximum is %d",
			ownerPack,
			len(rows),
			customPermissionManagedMaximumRows,
		)
	}
	states := make([]*customPermissionState, 0, len(rows))
	seen := make(map[string]struct{}, len(rows))
	for _, row := range rows {
		state, decodeErr := decodeCustomPermissionState(row)
		if decodeErr != nil {
			return nil, decodeErr
		}
		if state.Projection.OwnerPack != ownerPack {
			return nil, fmt.Errorf(
				"custom permission %s stored owner %q does not exactly match requested owner %q",
				state.Projection.APIName,
				state.Projection.OwnerPack,
				ownerPack,
			)
		}
		identity := strings.ToLower(state.Projection.APIName)
		if _, duplicate := seen[identity]; duplicate {
			return nil, fmt.Errorf(
				"custom permission owner set %s repeats API name %s under database collation",
				ownerPack,
				state.Projection.APIName,
			)
		}
		seen[identity] = struct{}{}
		states = append(states, state)
	}
	return states, nil
}

func rejectCustomPermissionRetirementReferences(
	ctx context.Context,
	store cp.ComponentManagedReadStore,
	state *customPermissionState,
	references []customPermissionRetirementReferenceSurface,
	lock bool,
) error {
	if len(references) == 0 {
		return fmt.Errorf("custom permission retirement reference inventory is empty")
	}
	for _, reference := range references {
		query := cp.ComponentManagedRowQuery{
			Table:             reference.Table,
			Columns:           []string{"Id"},
			Equal:             cp.ComponentRow{reference.Column: state.ID},
			LogicalKeyColumns: []string{"Id"},
			MaximumRows:       1,
		}
		var rows []cp.ComponentRow
		var err error
		if lock {
			mutationStore, ok := store.(cp.ComponentManagedMutationStore)
			if !ok {
				return fmt.Errorf("custom permission retirement reference lock requires mutation store")
			}
			rows, err = mutationStore.LockRows(ctx, query)
		} else {
			rows, err = store.ReadRows(ctx, query)
		}
		if err != nil {
			return fmt.Errorf("read custom permission retirement references in %s: %w", reference.Table, err)
		}
		if len(rows) != 0 {
			return fmt.Errorf(
				"custom permission %s cannot retire while referenced by %s",
				state.Projection.APIName,
				reference.Table,
			)
		}
	}
	return nil
}

func decodeCustomPermissionState(row cp.ComponentRow) (*customPermissionState, error) {
	id, err := permissionSetDefinitionRequiredString("_System_CustomPermission", row, "Id")
	if err != nil {
		return nil, err
	}
	apiName, err := permissionSetDefinitionRequiredString("_System_CustomPermission", row, "ApiName")
	if err != nil {
		return nil, err
	}
	if err := validateCustomPermissionIdentifier("stored API name", apiName, 255); err != nil {
		return nil, err
	}
	label, err := permissionSetDefinitionRequiredString("_System_CustomPermission", row, "Label")
	if err != nil {
		return nil, err
	}
	description, descriptionPresent, err := permissionSetDefinitionNullableString("_System_CustomPermission", row, "Description")
	if err != nil {
		return nil, err
	}
	active, err := permissionSetDefinitionRequiredBool("_System_CustomPermission", row, "IsActive")
	if err != nil {
		return nil, err
	}
	deleted, err := permissionSetDefinitionRequiredBool("_System_CustomPermission", row, "IsDeleted")
	if err != nil {
		return nil, err
	}
	customized, err := permissionSetDefinitionRequiredBool("_System_CustomPermission", row, "IsCustomized")
	if err != nil {
		return nil, err
	}
	ownerPack, _, err := permissionSetDefinitionNullableString("_System_CustomPermission", row, "OwnerPack")
	if err != nil {
		return nil, err
	}
	var descriptionPointer *string
	if descriptionPresent {
		descriptionPointer = &description
	}
	return &customPermissionState{
		ID: id,
		Projection: customPermissionProjection{
			Present:     true,
			APIName:     apiName,
			OwnerPack:   ownerPack,
			Label:       label,
			Description: descriptionPointer,
			Active:      active,
			Deleted:     deleted,
			Customized:  customized,
		},
	}, nil
}

func customPermissionItemAction(expected customPermissionProjection, state *customPermissionState) (customPermissionLifecycleAction, error) {
	if state == nil {
		return customPermissionLifecycleCreate, nil
	}
	if err := validateCustomPermissionOwner(expected, state); err != nil {
		return "", err
	}
	if state.Projection.Customized {
		return customPermissionLifecycleNoop, nil
	}
	if reflect.DeepEqual(state.Projection, expected) {
		return customPermissionLifecycleNoop, nil
	}
	return customPermissionLifecycleSync, nil
}

func validateCustomPermissionOwner(expected customPermissionProjection, state *customPermissionState) error {
	if state == nil || state.Projection.OwnerPack == expected.OwnerPack {
		return nil
	}
	return fmt.Errorf(
		"custom permission %s is owned by %q (row %s), cannot claim for %q",
		expected.APIName,
		state.Projection.OwnerPack,
		state.ID,
		expected.OwnerPack,
	)
}

func customPermissionDesiredRow(id string, expected customPermissionProjection) cp.ComponentRow {
	return cp.ComponentRow{
		"Id":           id,
		"ApiName":      expected.APIName,
		"Label":        expected.Label,
		"Description":  customPermissionDescriptionValue(expected.Description),
		"IsCustomized": false,
		"IsActive":     true,
		"IsDeleted":    false,
		"OwnerPack":    expected.OwnerPack,
	}
}

func customPermissionManagedSetTarget(packName string) cp.ComponentManagedTarget {
	return cp.ComponentManagedTarget{
		TargetDomain:     customPermissionManagedSetTargetDomain,
		PhysicalKeyBytes: []byte(strings.ToLower(packName)),
	}
}

func customPermissionDesiredSet(keys []string) (map[string]string, error) {
	if len(keys) > customPermissionManagedMaximumRows {
		return nil, fmt.Errorf(
			"desired custom permission set contains %d entries; maximum is %d",
			len(keys),
			customPermissionManagedMaximumRows,
		)
	}
	desired := make(map[string]string, len(keys))
	for _, key := range keys {
		if err := validateCustomPermissionIdentifier("API name", key, 255); err != nil {
			return nil, err
		}
		identity := strings.ToLower(key)
		if previous, duplicate := desired[identity]; duplicate {
			return nil, fmt.Errorf(
				"desired custom permission API names %q and %q collide under database collation",
				previous,
				key,
			)
		}
		desired[identity] = key
	}
	return desired, nil
}

func validateCustomPermissionSetRequest(request cp.ComponentManagedSetRequest) error {
	if err := validateCustomPermissionOwnerPack(request.PackName); err != nil {
		return err
	}
	if request.SourceOwner != "" {
		return fmt.Errorf("pack-owned custom permission set must not declare source owner %q", request.SourceOwner)
	}
	if request.Kind != customPermissionComponentKind {
		return fmt.Errorf("component kind = %q, want %q", request.Kind, customPermissionComponentKind)
	}
	return nil
}

func customPermissionItemProjectionIdentity(request cp.ComponentManagedRequest) []byte {
	return []byte(string(customPermissionComponentKind) + "\x00" + request.PackName + "\x00" + strings.ToLower(request.Component.BusinessKey))
}

func customPermissionSetProjectionIdentity(request cp.ComponentManagedSetRequest) []byte {
	return []byte(string(customPermissionComponentKind) + "\x00" + request.PackName + "\x00*")
}

func customPermissionItemCapabilities() []cp.ComponentManagedCapability {
	return []cp.ComponentManagedCapability{
		cp.ComponentManagedCapabilityTargetSerialization,
		cp.ComponentManagedCapabilityStructuredMutation,
		cp.ComponentManagedCapabilityEffects,
		cp.ComponentManagedCapabilityEvidence,
		cp.ComponentManagedCapabilityFreshProjection,
	}
}

func customPermissionSetCapabilities() []cp.ComponentManagedCapability {
	return append([]cp.ComponentManagedCapability{
		cp.ComponentManagedCapabilityExactSet,
	}, customPermissionItemCapabilities()...)
}

func customPermissionCollationOrderedNames(names []string) []string {
	ordered := append(make([]string, 0, len(names)), names...)
	sort.Slice(ordered, func(i, j int) bool {
		left, right := strings.ToLower(ordered[i]), strings.ToLower(ordered[j])
		if left == right {
			return ordered[i] < ordered[j]
		}
		return left < right
	})
	return ordered
}

func customPermissionDescriptionValue(description *string) any {
	if description == nil {
		return nil
	}
	return *description
}
