package layoutresolutionv1

import (
	"encoding/hex"
	"fmt"
	"strings"

	"github.com/pingcap-inc/nexuscrm-contract/pkg/catalogpublicationv1"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/layoutroutingsecurityv1"
)

// ValidateBinding validates the complete Catalog and security inputs and
// requires byte-identical org scope across the independent authorities.
func ValidateBinding(binding Binding) error {
	if err := catalogpublicationv1.ValidateCatalogSchemaBinding(binding.CatalogSchema); err != nil {
		return err
	}
	if err := validateDigest(binding.CatalogAssignmentIdentityViewDigest); err != nil {
		return fmt.Errorf("LayoutAssignmentResolutionBinding.CatalogAssignmentIdentityViewDigest: %w", err)
	}
	if err := layoutroutingsecurityv1.ValidateBinding(binding.RoutingSecurity); err != nil {
		return err
	}
	if binding.CatalogSchema.CatalogSnapshot.OrgID != binding.RoutingSecurity.OrgID {
		return fmt.Errorf("LayoutAssignmentResolutionBinding authority OrgIDs must match exactly")
	}
	return nil
}

func validateDigest(value string) error {
	const prefix = "sha256:"
	if len(value) != len(prefix)+64 || !strings.HasPrefix(value, prefix) {
		return fmt.Errorf("must be sha256:<64 lowercase hex>")
	}
	hexText := value[len(prefix):]
	if strings.ToLower(hexText) != hexText {
		return fmt.Errorf("hex must be lowercase")
	}
	if _, err := hex.DecodeString(hexText); err != nil {
		return fmt.Errorf("hex is invalid")
	}
	return nil
}
