package mapping

import (
	"context"

	catalogsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/catalog/consumerv1"
	commonsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/outboundintentv1"
	"github.com/pingcap-inc/nexuscrm-contract/wire-go/envelope"
	runtimev1 "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/runtime/v1"
	"google.golang.org/protobuf/proto"
)

func ToWireReadOutboundIntentGenerationRequest(
	ctx context.Context,
	request semantic.GenerationRequest,
) (*runtimev1.ReadOutboundIntentGenerationRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGenerationRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.ReadOutboundIntentGenerationRequest{
		AfterGeneration: request.AfterGeneration,
	}, nil
}

func FromWireReadOutboundIntentGenerationRequest(
	ctx context.Context,
	request *runtimev1.ReadOutboundIntentGenerationRequest,
) (semantic.GenerationRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.GenerationRequest{}, err
	}
	if request == nil {
		return semantic.GenerationRequest{}, invalidPlatformWire()
	}
	result := semantic.GenerationRequest{AfterGeneration: request.GetAfterGeneration()}
	if err := semantic.ValidateGenerationRequest(ctx, result); err != nil {
		return semantic.GenerationRequest{}, err
	}
	return result, nil
}

func ToWireReadOutboundIntentGenerationResponse(
	request semantic.GenerationRequest,
	response semantic.GenerationResponse,
) (*runtimev1.ReadOutboundIntentGenerationResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGenerationResponse(request, response); err != nil {
		return nil, err
	}
	return &runtimev1.ReadOutboundIntentGenerationResponse{
		Generation: response.Generation,
		Receipts: toWireReceipts(
			response.Receipts,
			platformCapability(semantic.CapabilityName),
		),
	}, nil
}

func FromWireReadOutboundIntentGenerationResponse(
	request semantic.GenerationRequest,
	response *runtimev1.ReadOutboundIntentGenerationResponse,
) (semantic.GenerationResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.GenerationResponse{}, err
	}
	if response == nil || response.GetReceipts() == nil {
		return semantic.GenerationResponse{}, incompatibleFailureFor(
			platformCapability(semantic.CapabilityName),
		)
	}
	receipts, err := fromWireReceipts(
		response.GetReceipts(),
		platformCapability(semantic.CapabilityName),
	)
	if err != nil {
		return semantic.GenerationResponse{}, err
	}
	result := semantic.GenerationResponse{
		Generation: response.GetGeneration(),
		Receipts:   receipts,
	}
	if err := semantic.ValidateGenerationResponse(request, result); err != nil {
		return semantic.GenerationResponse{}, err
	}
	return result, nil
}

func ToWireListPendingOutboundIntentsRequest(ctx context.Context, request semantic.ListRequest) (*runtimev1.ListPendingOutboundIntentsRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateListRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.ListPendingOutboundIntentsRequest{
		Limit: request.Limit, MinCatalogRevision: request.MinCatalogRevision,
		MaxOperationSetVersion: request.MaxOperationSetVersion,
	}, nil
}

func FromWireListPendingOutboundIntentsRequest(ctx context.Context, request *runtimev1.ListPendingOutboundIntentsRequest) (semantic.ListRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.ListRequest{}, err
	}
	if request == nil {
		return semantic.ListRequest{}, invalidPlatformWire()
	}
	result := semantic.ListRequest{
		Limit: request.GetLimit(), MinCatalogRevision: request.MinCatalogRevision,
		MaxOperationSetVersion: request.GetMaxOperationSetVersion(),
	}
	if err := semantic.ValidateListRequest(ctx, result); err != nil {
		return semantic.ListRequest{}, err
	}
	return result, nil
}

func ToWireListPendingOutboundIntentsResponse(request semantic.ListRequest, response semantic.ListResponse) (*runtimev1.ListPendingOutboundIntentsResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateListResponseFor(request, response); err != nil {
		return nil, err
	}
	result := &runtimev1.ListPendingOutboundIntentsResponse{Intents: make([]*runtimev1.OutboundIntent, 0, len(response.Intents)), Receipts: toWireReceipts(response.Receipts, platformCapability(semantic.CapabilityName))}
	for _, intent := range response.Intents {
		result.Intents = append(result.Intents, toWireOutboundIntent(intent))
	}
	if proto.Size(result) > envelope.MaxResponseWireBytes {
		return nil, &commonsemantic.Failure{
			Category:  commonsemantic.FailureResourceExhausted,
			LimitKind: commonsemantic.LimitWireFrame,
			Maximum:   envelope.MaxResponseWireBytes,
		}
	}
	return result, nil
}

func FromWireListPendingOutboundIntentsResponse(request semantic.ListRequest, response *runtimev1.ListPendingOutboundIntentsResponse) (semantic.ListResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.ListResponse{}, err
	}
	if response == nil || response.GetReceipts() == nil {
		return semantic.ListResponse{}, incompatibleFailureFor(platformCapability(semantic.CapabilityName))
	}
	if proto.Size(response) > envelope.MaxResponseWireBytes {
		return semantic.ListResponse{}, &commonsemantic.Failure{
			Category:  commonsemantic.FailureResourceExhausted,
			LimitKind: commonsemantic.LimitWireFrame,
			Maximum:   envelope.MaxResponseWireBytes,
		}
	}
	receipts, err := fromWireReceipts(response.GetReceipts(), platformCapability(semantic.CapabilityName))
	if err != nil {
		return semantic.ListResponse{}, err
	}
	result := semantic.ListResponse{Intents: make([]semantic.Intent, 0, len(response.GetIntents())), Receipts: receipts}
	for _, intent := range response.GetIntents() {
		converted, ok := fromWireOutboundIntent(intent)
		if !ok {
			return semantic.ListResponse{}, internalPlatformWire()
		}
		result.Intents = append(result.Intents, converted)
	}
	if err := semantic.ValidateListResponseFor(request, result); err != nil {
		return semantic.ListResponse{}, err
	}
	return result, nil
}

func ToWireAcknowledgeOutboundIntentRequest(ctx context.Context, request semantic.AcknowledgeRequest) (*runtimev1.AcknowledgeOutboundIntentRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateAcknowledgeRequest(ctx, request); err != nil {
		return nil, err
	}
	outcome, ok := toWireOutboundAdmissionOutcome(request.Outcome)
	if !ok {
		return nil, invalidPlatformWire()
	}
	return &runtimev1.AcknowledgeOutboundIntentRequest{IntentId: request.IntentID, PayloadDigest: request.PayloadDigest, CatalogRevision: request.CatalogRevision, Outcome: outcome, IntegrationCommandId: request.IntegrationCommandID, RejectionCode: request.RejectionCode}, nil
}

func FromWireAcknowledgeOutboundIntentRequest(ctx context.Context, request *runtimev1.AcknowledgeOutboundIntentRequest) (semantic.AcknowledgeRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.AcknowledgeRequest{}, err
	}
	if request == nil {
		return semantic.AcknowledgeRequest{}, invalidPlatformWire()
	}
	outcome, ok := fromWireOutboundAdmissionOutcome(request.GetOutcome())
	if !ok {
		return semantic.AcknowledgeRequest{}, invalidPlatformWire()
	}
	result := semantic.AcknowledgeRequest{IntentID: request.GetIntentId(), PayloadDigest: request.GetPayloadDigest(), CatalogRevision: request.GetCatalogRevision(), Outcome: outcome, IntegrationCommandID: request.GetIntegrationCommandId(), RejectionCode: request.GetRejectionCode()}
	if err := semantic.ValidateAcknowledgeRequest(ctx, result); err != nil {
		return semantic.AcknowledgeRequest{}, err
	}
	return result, nil
}

func ToWireAcknowledgeOutboundIntentResponse(request semantic.AcknowledgeRequest, response semantic.AcknowledgeResponse) (*runtimev1.AcknowledgeOutboundIntentResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateAcknowledgeResponse(request, response); err != nil {
		return nil, err
	}
	outcome, ok := toWireOutboundAdmissionOutcome(response.Outcome)
	if !ok {
		return nil, internalPlatformWire()
	}
	return &runtimev1.AcknowledgeOutboundIntentResponse{IntentId: response.IntentID, Outcome: outcome, Duplicate: response.Duplicate, Receipts: toWireReceipts(response.Receipts, platformCapability(semantic.CapabilityName))}, nil
}

func FromWireAcknowledgeOutboundIntentResponse(request semantic.AcknowledgeRequest, response *runtimev1.AcknowledgeOutboundIntentResponse) (semantic.AcknowledgeResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.AcknowledgeResponse{}, err
	}
	if response == nil || response.GetReceipts() == nil {
		return semantic.AcknowledgeResponse{}, incompatibleFailureFor(platformCapability(semantic.CapabilityName))
	}
	outcome, ok := fromWireOutboundAdmissionOutcome(response.GetOutcome())
	if !ok {
		return semantic.AcknowledgeResponse{}, internalPlatformWire()
	}
	receipts, err := fromWireReceipts(response.GetReceipts(), platformCapability(semantic.CapabilityName))
	if err != nil {
		return semantic.AcknowledgeResponse{}, err
	}
	result := semantic.AcknowledgeResponse{IntentID: response.GetIntentId(), Outcome: outcome, Duplicate: response.GetDuplicate(), Receipts: receipts}
	if err := semantic.ValidateAcknowledgeResponse(request, result); err != nil {
		return semantic.AcknowledgeResponse{}, err
	}
	return result, nil
}

func ToWireCommitOutboundResultRequest(ctx context.Context, request semantic.CommitResultRequest) (*runtimev1.CommitOutboundResultRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateCommitResultRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.CommitOutboundResultRequest{
		IntentId: request.IntentID, PayloadDigest: request.PayloadDigest,
		CatalogRevision:      request.CatalogRevision,
		IntegrationCommandId: request.IntegrationCommandID, RemoteId: request.RemoteID,
		ResultFormatVersion: request.ResultFormatVersion, ResultDigest: request.ResultDigest,
		CanonicalResult: append([]byte(nil), request.CanonicalResult...),
	}, nil
}

func FromWireCommitOutboundResultRequest(ctx context.Context, request *runtimev1.CommitOutboundResultRequest) (semantic.CommitResultRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.CommitResultRequest{}, err
	}
	if request == nil {
		return semantic.CommitResultRequest{}, invalidPlatformWire()
	}
	result := semantic.CommitResultRequest{
		IntentID: request.GetIntentId(), PayloadDigest: request.GetPayloadDigest(),
		CatalogRevision:      request.GetCatalogRevision(),
		IntegrationCommandID: request.GetIntegrationCommandId(), RemoteID: request.GetRemoteId(),
		ResultFormatVersion: request.GetResultFormatVersion(), ResultDigest: request.GetResultDigest(),
		CanonicalResult: append([]byte(nil), request.GetCanonicalResult()...),
	}
	if err := semantic.ValidateCommitResultRequest(ctx, result); err != nil {
		return semantic.CommitResultRequest{}, err
	}
	return result, nil
}

func ToWireCommitOutboundResultResponse(request semantic.CommitResultRequest, response semantic.CommitResultResponse) (*runtimev1.CommitOutboundResultResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateCommitResultResponse(request, response); err != nil {
		return nil, err
	}
	return &runtimev1.CommitOutboundResultResponse{
		IntentId: response.IntentID, Duplicate: response.Duplicate,
		Receipts: toWireReceipts(response.Receipts, platformCapability(semantic.CapabilityName)),
	}, nil
}

func FromWireCommitOutboundResultResponse(request semantic.CommitResultRequest, response *runtimev1.CommitOutboundResultResponse) (semantic.CommitResultResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.CommitResultResponse{}, err
	}
	if response == nil || response.GetReceipts() == nil {
		return semantic.CommitResultResponse{}, incompatibleFailureFor(platformCapability(semantic.CapabilityName))
	}
	receipts, err := fromWireReceipts(response.GetReceipts(), platformCapability(semantic.CapabilityName))
	if err != nil {
		return semantic.CommitResultResponse{}, err
	}
	result := semantic.CommitResultResponse{
		IntentID: response.GetIntentId(), Duplicate: response.GetDuplicate(), Receipts: receipts,
	}
	if err := semantic.ValidateCommitResultResponse(request, result); err != nil {
		return semantic.CommitResultResponse{}, err
	}
	return result, nil
}

func ToWireCommitOutboundNoEffectRequest(ctx context.Context, request semantic.CommitNoEffectRequest) (*runtimev1.CommitOutboundNoEffectRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateCommitNoEffectRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.CommitOutboundNoEffectRequest{
		IntentId: request.IntentID, PayloadDigest: request.PayloadDigest,
		CatalogRevision: request.CatalogRevision, IntegrationCommandId: request.IntegrationCommandID,
		Reason: string(request.Reason),
	}, nil
}

func FromWireCommitOutboundNoEffectRequest(ctx context.Context, request *runtimev1.CommitOutboundNoEffectRequest) (semantic.CommitNoEffectRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.CommitNoEffectRequest{}, err
	}
	if request == nil {
		return semantic.CommitNoEffectRequest{}, invalidPlatformWire()
	}
	result := semantic.CommitNoEffectRequest{
		IntentID: request.GetIntentId(), PayloadDigest: request.GetPayloadDigest(),
		CatalogRevision: request.GetCatalogRevision(), IntegrationCommandID: request.GetIntegrationCommandId(),
		Reason: semantic.NoEffectReason(request.GetReason()),
	}
	if err := semantic.ValidateCommitNoEffectRequest(ctx, result); err != nil {
		return semantic.CommitNoEffectRequest{}, err
	}
	return result, nil
}

func ToWireCommitOutboundNoEffectResponse(request semantic.CommitNoEffectRequest, response semantic.CommitNoEffectResponse) (*runtimev1.CommitOutboundNoEffectResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateCommitNoEffectResponse(request, response); err != nil {
		return nil, err
	}
	return &runtimev1.CommitOutboundNoEffectResponse{
		IntentId: response.IntentID, Reason: string(response.Reason), Duplicate: response.Duplicate,
		Receipts: toWireReceipts(response.Receipts, platformCapability(semantic.CapabilityName)),
	}, nil
}

func FromWireCommitOutboundNoEffectResponse(request semantic.CommitNoEffectRequest, response *runtimev1.CommitOutboundNoEffectResponse) (semantic.CommitNoEffectResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.CommitNoEffectResponse{}, err
	}
	if response == nil || response.GetReceipts() == nil {
		return semantic.CommitNoEffectResponse{}, incompatibleFailureFor(platformCapability(semantic.CapabilityName))
	}
	receipts, err := fromWireReceipts(response.GetReceipts(), platformCapability(semantic.CapabilityName))
	if err != nil {
		return semantic.CommitNoEffectResponse{}, err
	}
	result := semantic.CommitNoEffectResponse{
		IntentID: response.GetIntentId(), Reason: semantic.NoEffectReason(response.GetReason()),
		Duplicate: response.GetDuplicate(), Receipts: receipts,
	}
	if err := semantic.ValidateCommitNoEffectResponse(request, result); err != nil {
		return semantic.CommitNoEffectResponse{}, err
	}
	return result, nil
}

func ToWireOpenOutboundMailAttachmentRequest(ctx context.Context, request semantic.OpenMailAttachmentRequest) (*runtimev1.OpenOutboundMailAttachmentRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateOpenMailAttachmentRequest(ctx, request); err != nil {
		return nil, err
	}
	return &runtimev1.OpenOutboundMailAttachmentRequest{
		IntentId: request.IntentID, PayloadDigest: request.PayloadDigest,
		CatalogRevision: request.CatalogRevision, IntegrationCommandId: request.IntegrationCommandID,
		AttachmentIndex: request.AttachmentIndex,
	}, nil
}

func FromWireOpenOutboundMailAttachmentRequest(ctx context.Context, request *runtimev1.OpenOutboundMailAttachmentRequest) (semantic.OpenMailAttachmentRequest, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.OpenMailAttachmentRequest{}, err
	}
	if request == nil {
		return semantic.OpenMailAttachmentRequest{}, invalidPlatformWire()
	}
	result := semantic.OpenMailAttachmentRequest{
		IntentID: request.GetIntentId(), PayloadDigest: request.GetPayloadDigest(),
		CatalogRevision: request.GetCatalogRevision(), IntegrationCommandID: request.GetIntegrationCommandId(),
		AttachmentIndex: request.GetAttachmentIndex(),
	}
	if err := semantic.ValidateOpenMailAttachmentRequest(ctx, result); err != nil {
		return semantic.OpenMailAttachmentRequest{}, err
	}
	return result, nil
}

func ToWireOpenOutboundMailAttachmentChunk(chunk semantic.MailAttachmentChunk) (*runtimev1.OpenOutboundMailAttachmentResponse, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateMailAttachmentChunk(chunk); err != nil {
		return nil, err
	}
	result := &runtimev1.OpenOutboundMailAttachmentResponse{
		FileName: chunk.FileName, ContentType: chunk.ContentType,
		ContentLength: chunk.ContentLength, ContentDigest: chunk.ContentDigest,
		Data: append([]byte(nil), chunk.Data...),
	}
	if chunk.Receipts != nil {
		result.Receipts = toWireReceipts(*chunk.Receipts, platformCapability(semantic.CapabilityName))
	}
	if proto.Size(result) > envelope.MaxResponseWireBytes {
		return nil, &commonsemantic.Failure{Category: commonsemantic.FailureResourceExhausted, LimitKind: commonsemantic.LimitWireFrame, Maximum: envelope.MaxResponseWireBytes}
	}
	return result, nil
}

func FromWireOpenOutboundMailAttachmentChunk(chunk *runtimev1.OpenOutboundMailAttachmentResponse) (semantic.MailAttachmentChunk, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.MailAttachmentChunk{}, err
	}
	if chunk == nil || proto.Size(chunk) > envelope.MaxResponseWireBytes {
		return semantic.MailAttachmentChunk{}, invalidPlatformWire()
	}
	result := semantic.MailAttachmentChunk{
		FileName: chunk.GetFileName(), ContentType: chunk.GetContentType(),
		ContentLength: chunk.GetContentLength(), ContentDigest: chunk.GetContentDigest(),
		Data: append([]byte(nil), chunk.GetData()...),
	}
	if chunk.GetReceipts() != nil {
		receipts, err := fromWireReceipts(chunk.GetReceipts(), platformCapability(semantic.CapabilityName))
		if err != nil {
			return semantic.MailAttachmentChunk{}, err
		}
		result.Receipts = &receipts
	}
	if err := semantic.ValidateMailAttachmentChunk(result); err != nil {
		return semantic.MailAttachmentChunk{}, err
	}
	return result, nil
}

func toWireOutboundIntent(intent semantic.Intent) *runtimev1.OutboundIntent {
	operation, _ := toWireOutboundOperation(intent.Operation)
	result := &runtimev1.OutboundIntent{IntentId: intent.IntentID, IdempotencyKey: intent.IdempotencyKey, LogicalEffectRootId: intent.EffectRootID, LogicalEffectGenerationId: intent.EffectGenerationID, PayloadFormatVersion: intent.PayloadFormatVersion, PayloadDigest: intent.PayloadDigest, CatalogRevision: intent.CatalogRevision, Operation: operation, SourceObject: intent.SourceObject, SourceRecordId: intent.SourceRecordID, ConnectorOwnerKey: intent.ConnectorOwnerKey, FlowDeveloperName: intent.FlowDeveloperName, FlowActionName: intent.FlowActionName, ActionSlotId: intent.ActionSlotID, DestinationSlotId: intent.DestinationSlotID, Bindings: make([]*runtimev1.OutboundIntentBindingReference, 0, len(intent.Bindings)), CanonicalPayload: append([]byte(nil), intent.CanonicalPayload...)}
	for _, binding := range intent.Bindings {
		result.Bindings = append(result.Bindings, &runtimev1.OutboundIntentBindingReference{Kind: string(binding.Kind), OwnerPack: binding.OwnerPack, PackInstallationId: binding.PackInstallationID, PackPayloadDigest: binding.PackPayloadDigest, BusinessKey: binding.BusinessKey, DefinitionVersion: binding.DefinitionVersion})
	}
	return result
}

func fromWireOutboundIntent(intent *runtimev1.OutboundIntent) (semantic.Intent, bool) {
	if intent == nil {
		return semantic.Intent{}, false
	}
	operation, ok := fromWireOutboundOperation(intent.GetOperation())
	if !ok {
		return semantic.Intent{}, false
	}
	result := semantic.Intent{IntentID: intent.GetIntentId(), IdempotencyKey: intent.GetIdempotencyKey(), EffectRootID: intent.GetLogicalEffectRootId(), EffectGenerationID: intent.GetLogicalEffectGenerationId(), PayloadFormatVersion: intent.GetPayloadFormatVersion(), PayloadDigest: intent.GetPayloadDigest(), CatalogRevision: intent.GetCatalogRevision(), Operation: operation, SourceObject: intent.GetSourceObject(), SourceRecordID: intent.GetSourceRecordId(), ConnectorOwnerKey: intent.GetConnectorOwnerKey(), FlowDeveloperName: intent.GetFlowDeveloperName(), FlowActionName: intent.GetFlowActionName(), ActionSlotID: intent.GetActionSlotId(), DestinationSlotID: intent.GetDestinationSlotId(), Bindings: make([]semantic.BindingReference, 0, len(intent.GetBindings())), CanonicalPayload: append([]byte(nil), intent.GetCanonicalPayload()...)}
	for _, binding := range intent.GetBindings() {
		if binding == nil {
			return semantic.Intent{}, false
		}
		result.Bindings = append(result.Bindings, semantic.BindingReference{Kind: catalogsemantic.IntegrationBindingKind(binding.GetKind()), OwnerPack: binding.GetOwnerPack(), PackInstallationID: binding.GetPackInstallationId(), PackPayloadDigest: binding.GetPackPayloadDigest(), BusinessKey: binding.GetBusinessKey(), DefinitionVersion: binding.GetDefinitionVersion()})
	}
	return result, true
}

func toWireOutboundOperation(value semantic.Operation) (runtimev1.OutboundIntentOperation, bool) {
	switch value {
	case semantic.OperationUpsert:
		return runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_UPSERT, true
	case semantic.OperationDelete:
		return runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_DELETE, true
	case semantic.OperationSendMail:
		return runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_SEND_MAIL, true
	default:
		return runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_UNSPECIFIED, false
	}
}
func fromWireOutboundOperation(value runtimev1.OutboundIntentOperation) (semantic.Operation, bool) {
	switch value {
	case runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_UPSERT:
		return semantic.OperationUpsert, true
	case runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_DELETE:
		return semantic.OperationDelete, true
	case runtimev1.OutboundIntentOperation_OUTBOUND_INTENT_OPERATION_SEND_MAIL:
		return semantic.OperationSendMail, true
	default:
		return "", false
	}
}
func toWireOutboundAdmissionOutcome(value semantic.AdmissionOutcome) (runtimev1.OutboundIntentAdmissionOutcome, bool) {
	switch value {
	case semantic.AdmissionAccepted:
		return runtimev1.OutboundIntentAdmissionOutcome_OUTBOUND_INTENT_ADMISSION_OUTCOME_ACCEPTED, true
	case semantic.AdmissionRejected:
		return runtimev1.OutboundIntentAdmissionOutcome_OUTBOUND_INTENT_ADMISSION_OUTCOME_REJECTED, true
	default:
		return runtimev1.OutboundIntentAdmissionOutcome_OUTBOUND_INTENT_ADMISSION_OUTCOME_UNSPECIFIED, false
	}
}
func fromWireOutboundAdmissionOutcome(value runtimev1.OutboundIntentAdmissionOutcome) (semantic.AdmissionOutcome, bool) {
	switch value {
	case runtimev1.OutboundIntentAdmissionOutcome_OUTBOUND_INTENT_ADMISSION_OUTCOME_ACCEPTED:
		return semantic.AdmissionAccepted, true
	case runtimev1.OutboundIntentAdmissionOutcome_OUTBOUND_INTENT_ADMISSION_OUTCOME_REJECTED:
		return semantic.AdmissionRejected, true
	default:
		return "", false
	}
}
