package contract

import "fmt"

// HistoryQueryErrorKind classifies neutral audit-history query failures. Dialect
// boundaries map these kinds to their own wire status/code.
type HistoryQueryErrorKind string

const (
	HistoryQueryErrorObjectPermissionDenied HistoryQueryErrorKind = "object_permission_denied"
	HistoryQueryErrorRecordVisibilityDenied HistoryQueryErrorKind = "record_visibility_denied"
	HistoryQueryErrorMalformed              HistoryQueryErrorKind = "malformed"
	HistoryQueryErrorUnavailable            HistoryQueryErrorKind = "unavailable"
	HistoryQueryErrorInternal               HistoryQueryErrorKind = "internal"
)

// HistoryQueryError is returned by the neutral Query.QueryHistory contract.
type HistoryQueryError struct {
	Kind    HistoryQueryErrorKind
	Message string
	Cause   error
}

func (e *HistoryQueryError) Error() string {
	if e == nil {
		return ""
	}
	if e.Message != "" {
		return e.Message
	}
	if e.Cause != nil {
		return e.Cause.Error()
	}
	return string(e.Kind)
}

func (e *HistoryQueryError) Unwrap() error {
	if e == nil {
		return nil
	}
	return e.Cause
}

// FieldDeniedByFLSError is the typed error returned when the audit history
// planner detects a predicate on a field the caller cannot read. It carries the
// field name only; dialect boundaries own the concrete wire error code.
type FieldDeniedByFLSError struct {
	FieldApiName string
}

func (e *FieldDeniedByFLSError) Error() string {
	return fmt.Sprintf("field %s is denied by FLS", e.FieldApiName)
}

func (e *FieldDeniedByFLSError) HTTPStatus() int { return 400 }
