package connector_callout

import (
	"errors"
	"fmt"
)

var (
	// ErrTerminalNonRetryable is returned when the server returns a 4xx/5xx
	// status that is not in the retryable set.
	ErrTerminalNonRetryable = errors.New("connector_callout: terminal non-retryable response")

	// ErrMaxAttemptsExceeded is returned when all retry attempts are exhausted
	// without a successful response.
	ErrMaxAttemptsExceeded = errors.New("connector_callout: max retry attempts exceeded")

	// ErrInvalidResponse is returned when a response body cannot be parsed per
	// the caller's expectation (e.g. invalid JSON in a paginated response).
	ErrInvalidResponse = errors.New("connector_callout: invalid response shape")

	// ErrCredentialUnavailable is returned when the credential resolver fails to
	// provide a secret value (missing definition, inactive pack, etc.).
	ErrCredentialUnavailable = errors.New("connector_callout: credential unavailable")

	// ErrEndpointUnavailable is returned when the endpoint resolver fails to
	// provide a base URL (missing definition, inactive pack, etc.).
	ErrEndpointUnavailable = errors.New("connector_callout: endpoint unavailable")

	// ErrEmptyBatch is returned by BatchRead when the ids slice is empty.
	ErrEmptyBatch = errors.New("connector_callout: batch ids empty")

	// ErrInvalidBatchSpec is returned when BatchSpec.MaxBatchSize < 1.
	ErrInvalidBatchSpec = errors.New("connector_callout: invalid batch spec")

	// ErrInvalidPageSpec is returned when a PageSpec field is invalid.
	ErrInvalidPageSpec = errors.New("connector_callout: invalid page spec")

	// ErrUnsupportedAuthType is returned when a NamedCredential declares an AuthType
	// that the engine does not know how to apply.
	ErrUnsupportedAuthType = errors.New("connector_callout: unsupported NamedCredential AuthType")

	// ErrInvalidRequest is returned when a CalloutRequest field fails pre-flight
	// validation (e.g. RelativePath contains a query string).
	ErrInvalidRequest = errors.New("connector_callout: invalid request")

	// ErrResponseTooLarge is returned when the response body exceeds the engine's
	// MaxResponseBytes limit. The body is intentionally NOT returned — callers
	// that receive this error must not assume any partial content.
	ErrResponseTooLarge = errors.New("connector_callout: response body exceeds max bytes")

	// ErrCredentialedEndpointMustBeHTTPS is returned when the resolved AuthType
	// would attach server-known credentials (Bearer / OAuth2 / Basic / empty
	// = default-Bearer) over a plain HTTP destination. Cleartext transport is
	// rejected fail-closed because the first runtime consumer of NamedCredential
	// secrets must not operationalize credential exfiltration over the network.
	// Custom auth is exempt: it does not inject server-known secrets.
	ErrCredentialedEndpointMustBeHTTPS = errors.New("connector_callout: credentialed auth type requires HTTPS destination")

	// ErrProfileNotFound is returned by LoadProfile when no row matches the
	// requested (OwnerPack, ProfileName). Fail-closed: the caller cannot
	// distinguish "row absent" from "row soft-deleted".
	ErrProfileNotFound = errors.New("connector callout profile not found")

	// ErrProfileUnavailable is returned by LoadProfile when the owning
	// connector pack is inactive (or the PackResolver is nil). Mirrors
	// webhook_secret_verifier.go's fail-closed pattern (ErrWebhookSecretNotAvailable).
	ErrProfileUnavailable = errors.New("connector callout profile unavailable")
)

// BatchChunkError carries the per-chunk context when BatchRead's underlying
// Engine.Do call returns an error. Callers can use errors.As to recover the
// chunk index range and the last CalloutResponse Engine.Do preserved on
// terminal and retry-exhausted failures.
type BatchChunkError struct {
	Start    int
	End      int
	Response CalloutResponse
	Err      error
}

func (e *BatchChunkError) Error() string {
	return fmt.Sprintf("connector_callout: BatchRead chunk [%d, %d) failed: %v", e.Start, e.End, e.Err)
}

func (e *BatchChunkError) Unwrap() error {
	return e.Err
}
