package mxgateway

import (
	"crypto/tls"
	"strings"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

// Options configures gateway connections.
type Options struct {
	// Endpoint is the gateway host:port address to dial.
	Endpoint string
	// APIKey is the bearer token attached to outgoing gRPC metadata.
	APIKey string
	// Plaintext disables TLS and uses insecure credentials when true.
	Plaintext bool
	// CACertFile points to a PEM file used to verify the gateway certificate.
	CACertFile string
	// ServerNameOverride overrides the TLS SNI/SAN name presented to the gateway.
	ServerNameOverride string
	// DialTimeout bounds the blocking Dial; zero applies a built-in default.
	DialTimeout time.Duration
	// CallTimeout bounds each unary RPC; zero applies a built-in default and
	// negative disables the bound entirely.
	CallTimeout time.Duration
	// TLSConfig supplies a custom TLS configuration; takes precedence over
	// CACertFile when TransportCredentials is unset.
	TLSConfig *tls.Config
	// TransportCredentials, when non-nil, overrides every other transport-level
	// option and is used as-is.
	TransportCredentials credentials.TransportCredentials
	// DialOptions are appended to the gRPC dial options after the defaults.
	DialOptions []grpc.DialOption
	// RequireCertificateValidation forces TLS certificate verification even when
	// no CACertFile is pinned. Default false: the gateway's self-signed cert is
	// accepted without verification (internal-tool posture).
	RequireCertificateValidation bool
}

// BrowseChildrenOptions configures lazy Galaxy hierarchy walks performed by
// (*GalaxyClient).Browse and (*LazyBrowseNode).Expand. All fields are optional;
// the zero value matches the dashboard default (no filters, all attributes per
// the server default).
type BrowseChildrenOptions struct {
	// CategoryIds restricts results to the listed Galaxy category ids when set.
	CategoryIds []int32
	// TemplateChainContains restricts results to objects whose template chain
	// contains any of the listed template tag names.
	TemplateChainContains []string
	// TagNameGlob restricts results to objects whose tag name matches the glob
	// pattern when non-empty.
	TagNameGlob string
	// IncludeAttributes overrides the server default for attribute inclusion when
	// non-nil. The pointer form mirrors the proto's optional field.
	IncludeAttributes *bool
	// AlarmBearingOnly limits results to alarm-bearing objects when true.
	AlarmBearingOnly bool
	// HistorizedOnly limits results to historized objects when true.
	HistorizedOnly bool
}

// RedactedAPIKey returns a display-safe representation of the configured API
// key for diagnostics and CLI output.
func (o Options) RedactedAPIKey() string {
	return RedactAPIKey(o.APIKey)
}

// RedactAPIKey hides credential material while keeping enough shape for
// troubleshooting whether a key was supplied.
func RedactAPIKey(apiKey string) string {
	if apiKey == "" {
		return ""
	}

	if len(apiKey) <= 8 {
		return "<redacted>"
	}

	prefix, suffix := apiKey[:4], apiKey[len(apiKey)-4:]
	return prefix + strings.Repeat("*", len(apiKey)-8) + suffix
}
