package packs

import (
	"fmt"
	"slices"
	"strings"
)

// LoadConnectorCalloutProfileOutboundCapabilities validates one exact,
// immutable connector-binding definition and returns its provider-authored
// durable outbound allowlist. The definition must be the canonical payload
// selected from the binding owner's verified generation; mutable live rows and
// current pack source are not accepted here.
func LoadConnectorCalloutProfileOutboundCapabilities(
	canonicalDefinition []byte,
	ownerPack string,
	businessKey string,
) ([]ConnectorCalloutProfileOutboundCapability, error) {
	ownerPack = strings.TrimSpace(ownerPack)
	profileName, err := connectorCalloutProfileNameFromBusinessKey(
		ownerPack,
		businessKey,
	)
	if err != nil {
		return nil, err
	}
	if len(canonicalDefinition) == 0 {
		return nil, fmt.Errorf(
			"connector callout profile %q canonical definition is required",
			businessKey,
		)
	}
	var definition connectorCalloutProfileDefinition
	if err := decodeStrictJSON(canonicalDefinition, &definition); err != nil {
		return nil, fmt.Errorf(
			"decode connector callout profile %q canonical definition: %w",
			businessKey,
			err,
		)
	}
	// Canonical definitions can belong to historical immutable generations.
	// Preserve the same narrow compatibility admitted by historical pack
	// reconstruction while still validating all current outbound authority.
	component, err := newConnectorCalloutProfileComponent(
		ownerPack,
		definition,
		withLegacyMissingBatchIDResponseFieldCompat(),
	)
	if err != nil {
		return nil, fmt.Errorf(
			"validate connector callout profile %q canonical definition: %w",
			businessKey,
			err,
		)
	}
	profile, ok := component.(*connectorCalloutProfileComponent)
	if !ok || profile.definition.ProfileName != profileName {
		return nil, fmt.Errorf(
			"connector callout profile %q canonical definition disagrees with its binding",
			businessKey,
		)
	}
	return slices.Clone(profile.definition.OutboundCapabilities), nil
}
