package runtimeapi

import (
	"context"
	"errors"

	"github.com/pingcap-inc/nexuscrm-api-host/runtimegrpc"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/applicationnavigationv1"
	common "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	"google.golang.org/grpc"
)

type ApplicationNavigationSelection struct {
	OrgID             string
	AppInstallationID string
	WorkloadID        string
	FrontendAppID     string
}
type ApplicationNavigationAdmission struct {
	selection ApplicationNavigationSelection
}
type applicationNavigationOwnerKey struct{}

func NewApplicationNavigationAdmission(selection ApplicationNavigationSelection) (*ApplicationNavigationAdmission, error) {
	for _, value := range []string{selection.OrgID, selection.AppInstallationID, selection.WorkloadID, selection.FrontendAppID} {
		if !semantic.ValidIdentifier(value) {
			return nil, errors.New("navigation admission requires exact org, installation, workload and frontend owner")
		}
	}
	return &ApplicationNavigationAdmission{selection: selection}, nil
}
func (a *ApplicationNavigationAdmission) UnaryServerInterceptor() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, request any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
		capability, ok := runtimegrpc.Capability(ctx)
		if !ok || capability != semantic.CapabilityName {
			return handler(ctx, request)
		}
		trusted, ok := trustedCallFromContext(ctx)
		if !ok {
			return nil, applicationNavigationStatus(ctx, &common.Failure{Category: common.FailureUnauthenticated})
		}
		if a == nil || trusted.orgID != a.selection.OrgID || trusted.appInstallationID != a.selection.AppInstallationID || trusted.callerWorkloadID != a.selection.WorkloadID {
			return nil, applicationNavigationStatus(ctx, &common.Failure{Category: common.FailureForbidden})
		}
		return handler(context.WithValue(ctx, applicationNavigationOwnerKey{}, a.selection.FrontendAppID), request)
	}
}
