package runtimeapi

import (
	"context"
	"errors"

	"github.com/pingcap-inc/nexuscrm-api-host/runtimegrpc"
	metadataadminsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/metadataadminreadv1"
	"google.golang.org/grpc"
)

// MetadataAdminReadSelection is deployment-owned workload admission. It does
// not select a Catalog handler, projection, artifact, or publication revision.
type MetadataAdminReadSelection struct {
	OrgID             string
	AppInstallationID string
	WorkloadID        string
}

// MetadataAdminReadAdmission binds the neutral read port to the one SFCRM
// workload authorized by the deployment. SecurityAdmission has already
// authenticated that workload and verified the delegated end-user session.
type MetadataAdminReadAdmission struct {
	selection MetadataAdminReadSelection
}

func NewMetadataAdminReadAdmission(
	selection MetadataAdminReadSelection,
) (*MetadataAdminReadAdmission, error) {
	if selection.OrgID == "" || selection.AppInstallationID == "" || selection.WorkloadID == "" {
		return nil, errors.New("runtime metadata administration read admission requires org, installation, and workload")
	}
	return &MetadataAdminReadAdmission{selection: selection}, nil
}

func (admission *MetadataAdminReadAdmission) 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 != metadataadminsemantic.CapabilityName {
			return handler(ctx, request)
		}
		admitted, err := admission.bind(ctx)
		if err != nil {
			return nil, runtimegrpc.StatusError(ctx, err)
		}
		return handler(admitted, request)
	}
}

func (admission *MetadataAdminReadAdmission) bind(ctx context.Context) (context.Context, error) {
	trusted, ok := trustedCallFromContext(ctx)
	if !ok {
		return nil, &metadataadminsemantic.Failure{
			Category: metadataadminsemantic.FailureUnauthenticated,
		}
	}
	if admission == nil || trusted.orgID != admission.selection.OrgID ||
		trusted.appInstallationID != admission.selection.AppInstallationID ||
		trusted.callerWorkloadID != admission.selection.WorkloadID {
		return nil, &metadataadminsemantic.Failure{
			Category: metadataadminsemantic.FailureForbidden,
		}
	}
	return ctx, nil
}
