package mapping

import (
	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/servingbindingv1"
	runtimev1 "github.com/pingcap-inc/nexuscrm-contract/wire-go/gen/runtime/v1"
)

// ToWireCatalogServingBinding maps one validated, Catalog-derived binding into
// its inert wire form. It does not select or accept a serving identity.
func ToWireCatalogServingBinding(binding semantic.Binding) (*runtimev1.CatalogServingBinding, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return nil, err
	}
	if err := semantic.Validate(binding); err != nil {
		return nil, err
	}
	return &runtimev1.CatalogServingBinding{
		OrgId:                     binding.OrgID,
		AppInstallationId:         binding.AppInstallationID,
		AppReleaseDigest:          binding.AppReleaseDigest,
		WorkloadId:                binding.WorkloadID,
		CanonicalResource:         binding.CanonicalResource,
		ToolContractDigest:        binding.ToolContractDigest,
		ScopeRouteReceiptDigest:   binding.ScopeRouteReceiptDigest,
		WorkloadCapabilityCeiling: append([]string(nil), binding.WorkloadCapabilityCeiling...),
		Receipts:                  toWireReceipts(binding.Receipts, platformCapability(semantic.CapabilityName)),
	}, nil
}

// FromWireCatalogServingBinding decodes only a complete binding carrying the
// new capability identity. Unknown or partial encodings fail closed.
func FromWireCatalogServingBinding(binding *runtimev1.CatalogServingBinding) (semantic.Binding, error) {
	if err := requirePlatformSemanticShape(semantic.CapabilityName); err != nil {
		return semantic.Binding{}, err
	}
	if binding == nil || binding.GetReceipts() == nil {
		return semantic.Binding{}, incompatibleFailureFor(platformCapability(semantic.CapabilityName))
	}
	receipts, err := fromWireReceipts(binding.GetReceipts(), platformCapability(semantic.CapabilityName))
	if err != nil {
		return semantic.Binding{}, err
	}
	result := semantic.Binding{
		OrgID:                     binding.GetOrgId(),
		AppInstallationID:         binding.GetAppInstallationId(),
		AppReleaseDigest:          binding.GetAppReleaseDigest(),
		WorkloadID:                binding.GetWorkloadId(),
		CanonicalResource:         binding.GetCanonicalResource(),
		ToolContractDigest:        binding.GetToolContractDigest(),
		ScopeRouteReceiptDigest:   binding.GetScopeRouteReceiptDigest(),
		WorkloadCapabilityCeiling: append([]string(nil), binding.GetWorkloadCapabilityCeiling()...),
		Receipts:                  receipts,
	}
	if err := semantic.Validate(result); err != nil {
		return semantic.Binding{}, err
	}
	return result, nil
}
