package runtimeapi

import (
	"errors"
	query "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/queryv1"
	mutation "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/recordmutationv1"
	"slices"
	"strings"
)

func validateUserAPICallers(callers []string) error {
	for i, caller := range callers {
		if caller == "" || strings.TrimSpace(caller) != caller || (i > 0 && callers[i-1] >= caller) {
			return errors.New("runtime serving: user API callers must be canonical and unique")
		}
	}
	return nil
}

func (s *ServingState) isUserAPICaller(caller, capability string) bool {
	return s != nil && slices.Contains(s.userAPICallers, caller) && (capability == query.CapabilityName || capability == mutation.CapabilityName)
}

// UserAPICallerCapabilities is an opt-in admission class for user clients, not
// a replacement Catalog handler or a workload-consumer grant. The operator
// owns caller authentication; the one prepared Catalog view owns installed API
// availability. A fresh Runtime security read supplies the epoch on every
// issuance/data attempt. No identity is remapped to another workload.
func (s *ServingState) UserAPICallerCapabilities(org, installation, caller string, epoch uint64) ([]string, bool) {
	if s == nil || !slices.Contains(s.userAPICallers, caller) {
		return nil, false
	}
	set := s.prepared.Load()
	if set == nil || epoch == 0 {
		return nil, true
	}
	var capabilities []string
	for _, capability := range []string{mutation.CapabilityName, query.CapabilityName} {
		p := set.byCapability[capability]
		if p != nil && p.selection.OrgID == org && p.selection.AppInstallationID == installation && p.selection.SecurityEpoch == epoch {
			capabilities = append(capabilities, capability)
		}
	}
	slices.Sort(capabilities)
	return capabilities, true
}
