package mapping

import (
	"context"

	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/catalog/consumerv1"
	commonsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	catalogv1 "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/catalog/v1"
)

func ToWireCatalogGetRequest(ctx context.Context, request semantic.GetRequest) (*catalogv1.GetAppMetadataViewRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGetRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewRequest{MinCatalogRevision: request.MinCatalogRevision}, nil
}

func FromWireCatalogGetRequest(ctx context.Context, request *catalogv1.GetAppMetadataViewRequest) (semantic.GetRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return semantic.GetRequest{}, err
	}
	if request == nil {
		return semantic.GetRequest{}, invalidPlatformWire()
	}
	result := semantic.GetRequest{MinCatalogRevision: request.MinCatalogRevision}
	if err := semantic.ValidateGetRequest(ctx, result); err != nil {
		return semantic.GetRequest{}, err
	}
	return result, nil
}

func ToWireCatalogGetV2Request(ctx context.Context, request semantic.GetRequest) (*catalogv1.GetAppMetadataViewV2Request, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGetRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewV2Request{MinCatalogRevision: request.MinCatalogRevision}, nil
}

func FromWireCatalogGetV2Request(ctx context.Context, request *catalogv1.GetAppMetadataViewV2Request) (semantic.GetRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return semantic.GetRequest{}, err
	}
	if request == nil {
		return semantic.GetRequest{}, invalidPlatformWire()
	}
	result := semantic.GetRequest{MinCatalogRevision: request.MinCatalogRevision}
	if err := semantic.ValidateGetRequest(ctx, result); err != nil {
		return semantic.GetRequest{}, err
	}
	return result, nil
}

func ToWireCatalogGetV3Request(ctx context.Context, request semantic.GetRequest) (*catalogv1.GetAppMetadataViewV3Request, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGetRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewV3Request{MinCatalogRevision: request.MinCatalogRevision}, nil
}

func FromWireCatalogGetV3Request(ctx context.Context, request *catalogv1.GetAppMetadataViewV3Request) (semantic.GetRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return semantic.GetRequest{}, err
	}
	if request == nil {
		return semantic.GetRequest{}, invalidPlatformWire()
	}
	result := semantic.GetRequest{MinCatalogRevision: request.MinCatalogRevision}
	if err := semantic.ValidateGetRequest(ctx, result); err != nil {
		return semantic.GetRequest{}, err
	}
	return result, nil
}

func ToWireIntegrationBindingGetRequest(ctx context.Context, request semantic.GetRequest) (*catalogv1.GetIntegrationBindingViewRequest, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateGetRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.GetIntegrationBindingViewRequest{MinCatalogRevision: request.MinCatalogRevision}, nil
}

func FromWireIntegrationBindingGetRequest(ctx context.Context, request *catalogv1.GetIntegrationBindingViewRequest) (semantic.GetRequest, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return semantic.GetRequest{}, err
	}
	if request == nil {
		return semantic.GetRequest{}, invalidPlatformWire()
	}
	result := semantic.GetRequest{MinCatalogRevision: request.MinCatalogRevision}
	if err := semantic.ValidateGetRequest(ctx, result); err != nil {
		return semantic.GetRequest{}, err
	}
	return result, nil
}

func ToWireAppMetadataWatchRequest(ctx context.Context, request semantic.WatchRequest) (*catalogv1.WatchAppMetadataViewRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateWatchRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewRequest{AfterCatalogRevision: request.AfterCatalogRevision}, nil
}

func FromWireAppMetadataWatchRequest(ctx context.Context, request *catalogv1.WatchAppMetadataViewRequest) (semantic.WatchRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return semantic.WatchRequest{}, err
	}
	if request == nil {
		return semantic.WatchRequest{}, invalidPlatformWire()
	}
	result := semantic.WatchRequest{AfterCatalogRevision: request.AfterCatalogRevision}
	if err := semantic.ValidateWatchRequest(ctx, result); err != nil {
		return semantic.WatchRequest{}, err
	}
	return result, nil
}

func ToWireAppMetadataV2WatchRequest(ctx context.Context, request semantic.WatchRequest) (*catalogv1.WatchAppMetadataViewV2Request, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateWatchRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewV2Request{AfterCatalogRevision: request.AfterCatalogRevision}, nil
}

func FromWireAppMetadataV2WatchRequest(ctx context.Context, request *catalogv1.WatchAppMetadataViewV2Request) (semantic.WatchRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return semantic.WatchRequest{}, err
	}
	if request == nil {
		return semantic.WatchRequest{}, invalidPlatformWire()
	}
	result := semantic.WatchRequest{AfterCatalogRevision: request.AfterCatalogRevision}
	if err := semantic.ValidateWatchRequest(ctx, result); err != nil {
		return semantic.WatchRequest{}, err
	}
	return result, nil
}

func ToWireAppMetadataV3WatchRequest(ctx context.Context, request semantic.WatchRequest) (*catalogv1.WatchAppMetadataViewV3Request, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateWatchRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewV3Request{AfterCatalogRevision: request.AfterCatalogRevision}, nil
}

func FromWireAppMetadataV3WatchRequest(ctx context.Context, request *catalogv1.WatchAppMetadataViewV3Request) (semantic.WatchRequest, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return semantic.WatchRequest{}, err
	}
	if request == nil {
		return semantic.WatchRequest{}, invalidPlatformWire()
	}
	result := semantic.WatchRequest{AfterCatalogRevision: request.AfterCatalogRevision}
	if err := semantic.ValidateWatchRequest(ctx, result); err != nil {
		return semantic.WatchRequest{}, err
	}
	return result, nil
}

func ToWireIntegrationBindingWatchRequest(ctx context.Context, request semantic.WatchRequest) (*catalogv1.WatchIntegrationBindingViewRequest, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateWatchRequest(ctx, request); err != nil {
		return nil, err
	}
	return &catalogv1.WatchIntegrationBindingViewRequest{AfterCatalogRevision: request.AfterCatalogRevision}, nil
}

func FromWireIntegrationBindingWatchRequest(ctx context.Context, request *catalogv1.WatchIntegrationBindingViewRequest) (semantic.WatchRequest, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return semantic.WatchRequest{}, err
	}
	if request == nil {
		return semantic.WatchRequest{}, invalidPlatformWire()
	}
	result := semantic.WatchRequest{AfterCatalogRevision: request.AfterCatalogRevision}
	if err := semantic.ValidateWatchRequest(ctx, result); err != nil {
		return semantic.WatchRequest{}, err
	}
	return result, nil
}

func ToWireAppMetadataView(view semantic.AppMetadataView) (*catalogv1.AppMetadataView, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateAppMetadataView(view); err != nil {
		return nil, err
	}
	components := toWireAppMetadataComponents(view.Components)
	return &catalogv1.AppMetadataView{
		OrgId: view.OrgID, AppInstallationId: view.AppInstallationID, AppId: view.AppID,
		AppReleaseDigest: view.AppReleaseDigest, Lineage: toWireConsumerViewLineage(view.Lineage),
		Components: components,
		Receipts:   toWireReceipts(view.Receipts, platformCapability(semantic.AppMetadataCapabilityName)),
	}, nil
}

func FromWireAppMetadataView(view *catalogv1.AppMetadataView) (semantic.AppMetadataView, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataCapabilityName); err != nil {
		return semantic.AppMetadataView{}, err
	}
	if view == nil || view.GetLineage() == nil || view.GetReceipts() == nil {
		return semantic.AppMetadataView{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataCapabilityName))
	}
	receipts, err := fromWireReceipts(view.GetReceipts(), platformCapability(semantic.AppMetadataCapabilityName))
	if err != nil {
		return semantic.AppMetadataView{}, err
	}
	result := semantic.AppMetadataView{
		OrgID: view.GetOrgId(), AppInstallationID: view.GetAppInstallationId(), AppID: view.GetAppId(),
		AppReleaseDigest: view.GetAppReleaseDigest(), Lineage: fromWireConsumerViewLineage(view.GetLineage()),
		Receipts: receipts,
	}
	result.Components, err = fromWireAppMetadataComponents(view.GetComponents())
	if err != nil {
		return semantic.AppMetadataView{}, err
	}
	if err := semantic.ValidateAppMetadataView(result); err != nil {
		return semantic.AppMetadataView{}, err
	}
	return result, nil
}

func ToWireAppMetadataViewV2(view semantic.AppMetadataViewV2) (*catalogv1.AppMetadataViewV2, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateAppMetadataViewV2(view); err != nil {
		return nil, err
	}
	effective := make([]*catalogv1.EffectiveMetadataComponent, 0, len(view.EffectiveComponents))
	for _, component := range view.EffectiveComponents {
		effective = append(effective, &catalogv1.EffectiveMetadataComponent{
			ComponentKind: component.ComponentKind, ComponentFormatVersion: component.ComponentFormatVersion,
			BusinessKey: component.BusinessKey, ContentDigest: component.ContentDigest,
			CanonicalBehavior: append([]byte(nil), component.CanonicalBehavior...),
		})
	}
	return &catalogv1.AppMetadataViewV2{
		OrgId: view.OrgID, AppInstallationId: view.AppInstallationID, AppId: view.AppID,
		AppReleaseDigest: view.AppReleaseDigest, Lineage: toWireConsumerViewLineage(view.Lineage),
		AppComponents: toWireAppMetadataComponents(view.AppComponents), EffectiveComponents: effective,
		Receipts: toWireReceipts(view.Receipts, platformCapability(semantic.AppMetadataV2CapabilityName)),
	}, nil
}

func FromWireAppMetadataViewV2(view *catalogv1.AppMetadataViewV2) (semantic.AppMetadataViewV2, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV2CapabilityName); err != nil {
		return semantic.AppMetadataViewV2{}, err
	}
	if view == nil || view.GetLineage() == nil || view.GetReceipts() == nil {
		return semantic.AppMetadataViewV2{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV2CapabilityName))
	}
	receipts, err := fromWireReceipts(view.GetReceipts(), platformCapability(semantic.AppMetadataV2CapabilityName))
	if err != nil {
		return semantic.AppMetadataViewV2{}, err
	}
	result := semantic.AppMetadataViewV2{
		OrgID: view.GetOrgId(), AppInstallationID: view.GetAppInstallationId(), AppID: view.GetAppId(),
		AppReleaseDigest: view.GetAppReleaseDigest(), Lineage: fromWireConsumerViewLineage(view.GetLineage()),
		Receipts: receipts,
	}
	result.AppComponents, err = fromWireAppMetadataComponents(view.GetAppComponents())
	if err != nil {
		return semantic.AppMetadataViewV2{}, err
	}
	result.EffectiveComponents = make([]semantic.EffectiveMetadataComponent, 0, len(view.GetEffectiveComponents()))
	for _, component := range view.GetEffectiveComponents() {
		if component == nil {
			return semantic.AppMetadataViewV2{}, internalPlatformWire()
		}
		result.EffectiveComponents = append(result.EffectiveComponents, semantic.EffectiveMetadataComponent{
			ComponentKind: component.GetComponentKind(), ComponentFormatVersion: component.GetComponentFormatVersion(),
			BusinessKey: component.GetBusinessKey(), ContentDigest: component.GetContentDigest(),
			CanonicalBehavior: append([]byte(nil), component.GetCanonicalBehavior()...),
		})
	}
	if err := semantic.ValidateAppMetadataViewV2(result); err != nil {
		return semantic.AppMetadataViewV2{}, err
	}
	return result, nil
}

func ToWireAppMetadataViewV3(view semantic.AppMetadataViewV3) (*catalogv1.AppMetadataViewV3, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateAppMetadataViewV3(view); err != nil {
		return nil, err
	}
	effective := make([]*catalogv1.EffectiveMetadataComponent, 0, len(view.EffectiveComponents))
	for _, component := range view.EffectiveComponents {
		effective = append(effective, &catalogv1.EffectiveMetadataComponent{
			ComponentKind: component.ComponentKind, ComponentFormatVersion: component.ComponentFormatVersion,
			BusinessKey: component.BusinessKey, ContentDigest: component.ContentDigest,
			CanonicalBehavior: append([]byte(nil), component.CanonicalBehavior...),
		})
	}
	return &catalogv1.AppMetadataViewV3{
		OrgId: view.OrgID, AppInstallationId: view.AppInstallationID, AppId: view.AppID,
		AppReleaseDigest: view.AppReleaseDigest, Lineage: toWireConsumerViewLineage(view.Lineage),
		AppComponents: toWireAppMetadataComponents(view.AppComponents), EffectiveComponents: effective,
		Receipts: toWireReceipts(view.Receipts, platformCapability(semantic.AppMetadataV3CapabilityName)),
	}, nil
}

func FromWireAppMetadataViewV3(view *catalogv1.AppMetadataViewV3) (semantic.AppMetadataViewV3, error) {
	if err := requirePlatformSemanticShape(semantic.AppMetadataV3CapabilityName); err != nil {
		return semantic.AppMetadataViewV3{}, err
	}
	if view == nil || view.GetLineage() == nil || view.GetReceipts() == nil {
		return semantic.AppMetadataViewV3{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV3CapabilityName))
	}
	receipts, err := fromWireReceipts(view.GetReceipts(), platformCapability(semantic.AppMetadataV3CapabilityName))
	if err != nil {
		return semantic.AppMetadataViewV3{}, err
	}
	result := semantic.AppMetadataViewV3{
		OrgID: view.GetOrgId(), AppInstallationID: view.GetAppInstallationId(), AppID: view.GetAppId(),
		AppReleaseDigest: view.GetAppReleaseDigest(), Lineage: fromWireConsumerViewLineage(view.GetLineage()),
		Receipts: receipts,
	}
	result.AppComponents, err = fromWireAppMetadataComponents(view.GetAppComponents())
	if err != nil {
		return semantic.AppMetadataViewV3{}, err
	}
	result.EffectiveComponents = make([]semantic.EffectiveMetadataComponent, 0, len(view.GetEffectiveComponents()))
	for _, component := range view.GetEffectiveComponents() {
		if component == nil {
			return semantic.AppMetadataViewV3{}, internalPlatformWire()
		}
		result.EffectiveComponents = append(result.EffectiveComponents, semantic.EffectiveMetadataComponent{
			ComponentKind: component.GetComponentKind(), ComponentFormatVersion: component.GetComponentFormatVersion(),
			BusinessKey: component.GetBusinessKey(), ContentDigest: component.GetContentDigest(),
			CanonicalBehavior: append([]byte(nil), component.GetCanonicalBehavior()...),
		})
	}
	if err := semantic.ValidateAppMetadataViewV3(result); err != nil {
		return semantic.AppMetadataViewV3{}, err
	}
	return result, nil
}

func ToWireIntegrationBindingView(view semantic.IntegrationBindingView) (*catalogv1.IntegrationBindingView, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.ValidateIntegrationBindingView(view); err != nil {
		return nil, err
	}
	bindings := make([]*catalogv1.IntegrationBinding, 0, len(view.Bindings))
	for _, binding := range view.Bindings {
		kind, ok := toWireIntegrationBindingKind(binding.Kind)
		if !ok {
			return nil, internalPlatformWire()
		}
		wireBinding := &catalogv1.IntegrationBinding{
			Kind: kind, OwnerPack: binding.OwnerPack,
			PackInstallationId: binding.PackInstallationID, PackPayloadDigest: binding.PackPayloadDigest,
			BusinessKey: binding.BusinessKey, DefinitionVersion: binding.DefinitionVersion,
			CredentialRefs: append([]string(nil), binding.CredentialRefs...),
		}
		if binding.RuntimeCommand != nil {
			wireBinding.RuntimeCommand = &catalogv1.RuntimeCommandBinding{
				CommandKind:          binding.RuntimeCommand.CommandKind,
				PayloadFormatVersion: binding.RuntimeCommand.PayloadFormatVersion,
				DefinitionRef:        binding.RuntimeCommand.DefinitionRef,
				DefinitionVersion:    binding.RuntimeCommand.DefinitionVersion,
			}
		}
		bindings = append(bindings, wireBinding)
	}
	return &catalogv1.IntegrationBindingView{
		OrgId: view.OrgID, AppInstallationId: view.AppInstallationID,
		AuthorizedWorkloadId: view.AuthorizedWorkloadID, Lineage: toWireConsumerViewLineage(view.Lineage),
		Bindings: bindings,
		Receipts: toWireReceipts(view.Receipts, platformCapability(semantic.IntegrationBindingCapabilityName)),
	}, nil
}

func FromWireIntegrationBindingView(view *catalogv1.IntegrationBindingView) (semantic.IntegrationBindingView, error) {
	if err := requirePlatformSemanticShape(semantic.IntegrationBindingCapabilityName); err != nil {
		return semantic.IntegrationBindingView{}, err
	}
	if view == nil || view.GetLineage() == nil || view.GetReceipts() == nil {
		return semantic.IntegrationBindingView{}, incompatibleFailureFor(platformCapability(semantic.IntegrationBindingCapabilityName))
	}
	receipts, err := fromWireReceipts(view.GetReceipts(), platformCapability(semantic.IntegrationBindingCapabilityName))
	if err != nil {
		return semantic.IntegrationBindingView{}, err
	}
	result := semantic.IntegrationBindingView{
		OrgID: view.GetOrgId(), AppInstallationID: view.GetAppInstallationId(),
		AuthorizedWorkloadID: view.GetAuthorizedWorkloadId(), Lineage: fromWireConsumerViewLineage(view.GetLineage()),
		Receipts: receipts, Bindings: make([]semantic.IntegrationBinding, 0, len(view.GetBindings())),
	}
	for _, binding := range view.GetBindings() {
		if binding == nil {
			return semantic.IntegrationBindingView{}, internalPlatformWire()
		}
		kind, ok := fromWireIntegrationBindingKind(binding.GetKind())
		if !ok {
			return semantic.IntegrationBindingView{}, internalPlatformWire()
		}
		semanticBinding := semantic.IntegrationBinding{
			Kind: kind, OwnerPack: binding.GetOwnerPack(), PackInstallationID: binding.GetPackInstallationId(),
			PackPayloadDigest: binding.GetPackPayloadDigest(), BusinessKey: binding.GetBusinessKey(),
			DefinitionVersion: binding.GetDefinitionVersion(), CredentialRefs: append([]string(nil), binding.GetCredentialRefs()...),
		}
		if command := binding.GetRuntimeCommand(); command != nil {
			semanticBinding.RuntimeCommand = &semantic.RuntimeCommandBinding{
				CommandKind: command.GetCommandKind(), PayloadFormatVersion: command.GetPayloadFormatVersion(),
				DefinitionRef: command.GetDefinitionRef(), DefinitionVersion: command.GetDefinitionVersion(),
			}
		}
		result.Bindings = append(result.Bindings, semanticBinding)
	}
	if err := semantic.ValidateIntegrationBindingView(result); err != nil {
		return semantic.IntegrationBindingView{}, err
	}
	return result, nil
}

func ToWireGetAppMetadataViewResponse(view semantic.AppMetadataView) (*catalogv1.GetAppMetadataViewResponse, error) {
	wireView, err := ToWireAppMetadataView(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewResponse{View: wireView}, nil
}

func FromWireGetAppMetadataViewResponse(response *catalogv1.GetAppMetadataViewResponse) (semantic.AppMetadataView, error) {
	if response == nil {
		return semantic.AppMetadataView{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataCapabilityName))
	}
	return FromWireAppMetadataView(response.GetView())
}

func ToWireWatchAppMetadataViewResponse(view semantic.AppMetadataView) (*catalogv1.WatchAppMetadataViewResponse, error) {
	wireView, err := ToWireAppMetadataView(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewResponse{View: wireView}, nil
}

func FromWireWatchAppMetadataViewResponse(response *catalogv1.WatchAppMetadataViewResponse) (semantic.AppMetadataView, error) {
	if response == nil {
		return semantic.AppMetadataView{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataCapabilityName))
	}
	return FromWireAppMetadataView(response.GetView())
}

func ToWireGetAppMetadataViewV2Response(view semantic.AppMetadataViewV2) (*catalogv1.GetAppMetadataViewV2Response, error) {
	wireView, err := ToWireAppMetadataViewV2(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewV2Response{View: wireView}, nil
}

func FromWireGetAppMetadataViewV2Response(response *catalogv1.GetAppMetadataViewV2Response) (semantic.AppMetadataViewV2, error) {
	if response == nil {
		return semantic.AppMetadataViewV2{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV2CapabilityName))
	}
	return FromWireAppMetadataViewV2(response.GetView())
}

func ToWireWatchAppMetadataViewV2Response(view semantic.AppMetadataViewV2) (*catalogv1.WatchAppMetadataViewV2Response, error) {
	wireView, err := ToWireAppMetadataViewV2(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewV2Response{View: wireView}, nil
}

func FromWireWatchAppMetadataViewV2Response(response *catalogv1.WatchAppMetadataViewV2Response) (semantic.AppMetadataViewV2, error) {
	if response == nil {
		return semantic.AppMetadataViewV2{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV2CapabilityName))
	}
	return FromWireAppMetadataViewV2(response.GetView())
}

func ToWireGetAppMetadataViewV3Response(view semantic.AppMetadataViewV3) (*catalogv1.GetAppMetadataViewV3Response, error) {
	wireView, err := ToWireAppMetadataViewV3(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.GetAppMetadataViewV3Response{View: wireView}, nil
}

func FromWireGetAppMetadataViewV3Response(response *catalogv1.GetAppMetadataViewV3Response) (semantic.AppMetadataViewV3, error) {
	if response == nil {
		return semantic.AppMetadataViewV3{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV3CapabilityName))
	}
	return FromWireAppMetadataViewV3(response.GetView())
}

func ToWireWatchAppMetadataViewV3Response(view semantic.AppMetadataViewV3) (*catalogv1.WatchAppMetadataViewV3Response, error) {
	wireView, err := ToWireAppMetadataViewV3(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.WatchAppMetadataViewV3Response{View: wireView}, nil
}

func FromWireWatchAppMetadataViewV3Response(response *catalogv1.WatchAppMetadataViewV3Response) (semantic.AppMetadataViewV3, error) {
	if response == nil {
		return semantic.AppMetadataViewV3{}, incompatibleFailureFor(platformCapability(semantic.AppMetadataV3CapabilityName))
	}
	return FromWireAppMetadataViewV3(response.GetView())
}

func ToWireGetIntegrationBindingViewResponse(view semantic.IntegrationBindingView) (*catalogv1.GetIntegrationBindingViewResponse, error) {
	wireView, err := ToWireIntegrationBindingView(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.GetIntegrationBindingViewResponse{View: wireView}, nil
}

func FromWireGetIntegrationBindingViewResponse(response *catalogv1.GetIntegrationBindingViewResponse) (semantic.IntegrationBindingView, error) {
	if response == nil {
		return semantic.IntegrationBindingView{}, incompatibleFailureFor(platformCapability(semantic.IntegrationBindingCapabilityName))
	}
	return FromWireIntegrationBindingView(response.GetView())
}

func ToWireWatchIntegrationBindingViewResponse(view semantic.IntegrationBindingView) (*catalogv1.WatchIntegrationBindingViewResponse, error) {
	wireView, err := ToWireIntegrationBindingView(view)
	if err != nil {
		return nil, err
	}
	return &catalogv1.WatchIntegrationBindingViewResponse{View: wireView}, nil
}

func FromWireWatchIntegrationBindingViewResponse(response *catalogv1.WatchIntegrationBindingViewResponse) (semantic.IntegrationBindingView, error) {
	if response == nil {
		return semantic.IntegrationBindingView{}, incompatibleFailureFor(platformCapability(semantic.IntegrationBindingCapabilityName))
	}
	return FromWireIntegrationBindingView(response.GetView())
}

func toWireConsumerViewLineage(lineage semantic.ViewLineage) *catalogv1.ConsumerViewLineage {
	return &catalogv1.ConsumerViewLineage{
		CatalogRevision: lineage.CatalogRevision, SchemaGeneration: lineage.SchemaGeneration,
		EngineGeneration: lineage.EngineGeneration, SourceSnapshotDigest: lineage.SourceSnapshotDigest,
		ViewDigest: lineage.ViewDigest,
	}
}

func fromWireConsumerViewLineage(lineage *catalogv1.ConsumerViewLineage) semantic.ViewLineage {
	return semantic.ViewLineage{
		CatalogRevision: lineage.GetCatalogRevision(), SchemaGeneration: lineage.GetSchemaGeneration(),
		EngineGeneration: lineage.GetEngineGeneration(), SourceSnapshotDigest: lineage.GetSourceSnapshotDigest(),
		ViewDigest: lineage.GetViewDigest(),
	}
}

func toWireAppMetadataComponents(values []semantic.AppMetadataComponent) []*catalogv1.AppMetadataComponent {
	result := make([]*catalogv1.AppMetadataComponent, 0, len(values))
	for _, component := range values {
		result = append(result, &catalogv1.AppMetadataComponent{
			ComponentId: component.ComponentID, ComponentKind: component.ComponentKind,
			ComponentFormatVersion: component.ComponentFormatVersion, NamespaceId: component.NamespaceID,
			BusinessKey: component.BusinessKey, DefinitionVersion: component.DefinitionVersion,
			ContentDigest: component.ContentDigest, CanonicalBehavior: append([]byte(nil), component.CanonicalBehavior...),
		})
	}
	return result
}

func fromWireAppMetadataComponents(values []*catalogv1.AppMetadataComponent) ([]semantic.AppMetadataComponent, error) {
	result := make([]semantic.AppMetadataComponent, 0, len(values))
	for _, component := range values {
		if component == nil {
			return nil, internalPlatformWire()
		}
		result = append(result, semantic.AppMetadataComponent{
			ComponentID: component.GetComponentId(), ComponentKind: component.GetComponentKind(),
			ComponentFormatVersion: component.GetComponentFormatVersion(), NamespaceID: component.GetNamespaceId(),
			BusinessKey: component.GetBusinessKey(), DefinitionVersion: component.GetDefinitionVersion(),
			ContentDigest: component.GetContentDigest(), CanonicalBehavior: append([]byte(nil), component.GetCanonicalBehavior()...),
		})
	}
	return result, nil
}

func toWireIntegrationBindingKind(kind semantic.IntegrationBindingKind) (catalogv1.IntegrationBindingKind, bool) {
	result, ok := map[semantic.IntegrationBindingKind]catalogv1.IntegrationBindingKind{
		semantic.BindingConnectorInboundRoute:   catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_INBOUND_ROUTE,
		semantic.BindingConnectorCalloutProfile: catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_CALLOUT_PROFILE,
		semantic.BindingConnectorFieldMapping:   catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_FIELD_MAPPING,
		semantic.BindingConnectorPushContract:   catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_PUSH_CONTRACT,
	}[kind]
	return result, ok
}

func fromWireIntegrationBindingKind(kind catalogv1.IntegrationBindingKind) (semantic.IntegrationBindingKind, bool) {
	result, ok := map[catalogv1.IntegrationBindingKind]semantic.IntegrationBindingKind{
		catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_INBOUND_ROUTE:   semantic.BindingConnectorInboundRoute,
		catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_CALLOUT_PROFILE: semantic.BindingConnectorCalloutProfile,
		catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_FIELD_MAPPING:   semantic.BindingConnectorFieldMapping,
		catalogv1.IntegrationBindingKind_INTEGRATION_BINDING_KIND_CONNECTOR_PUSH_CONTRACT:   semantic.BindingConnectorPushContract,
	}[kind]
	return result, ok
}

func invalidPlatformWire() error {
	return &commonsemantic.Failure{
		Category: commonsemantic.FailureInvalidRequest, InvalidComponent: commonsemantic.InvalidComponentResponse,
	}
}

func internalPlatformWire() error {
	return &commonsemantic.Failure{Category: commonsemantic.FailureInternal}
}
