package config

// Default provider-pool queue policy values. These are the only canonical
// defaults and are referenced by config, load, refresh, and admission paths.
const (
	DefaultProviderPoolMaxQueue       = 16
	DefaultProviderPoolQueueTimeoutMS = 30000
)

// EdgeProviderPoolConf is the Edge root-level queue policy that the runtime
// treats as the canonical, shared owner for every provider candidate in the
// pool. Legacy per-provider max_queue/queue_timeout_ms fields remain in
// NodeProviderConf only as compatibility carry-over and never influence the
// effective policy after LoadEdge migration.
type EdgeProviderPoolConf struct {
	// MaxQueue is the maximum queue depth for the entire provider pool.
	// Zero on decode is normalized to DefaultProviderPoolMaxQueue.
	MaxQueue int `mapstructure:"max_queue" yaml:"max_queue"`
	// QueueTimeoutMS is the per-request queue timeout in milliseconds.
	// Explicit 0 preserves the legacy no-timeout behavior and is intentionally
	// distinct from the default 30000.
	QueueTimeoutMS int `mapstructure:"queue_timeout_ms" yaml:"queue_timeout_ms"`
}

type EdgeConfig struct {
	Edge         EdgeInfo             `mapstructure:"edge"          yaml:"edge"`
	Server       EdgeServerConf       `mapstructure:"server"        yaml:"server"`
	Bootstrap    EdgeBootstrapConf    `mapstructure:"bootstrap"     yaml:"bootstrap"`
	OpenAI       EdgeOpenAIConf       `mapstructure:"openai"        yaml:"openai"`
	A2A          EdgeA2AConf          `mapstructure:"a2a"           yaml:"a2a"`
	TLS          TLSConf              `mapstructure:"tls"           yaml:"tls"`
	Logging      LoggingConf          `mapstructure:"logging"       yaml:"logging"`
	Metrics      MetricsConf          `mapstructure:"metrics"       yaml:"metrics"`
	Console      EdgeConsoleConf      `mapstructure:"console"       yaml:"console"`
	ControlPlane EdgeControlPlaneConf `mapstructure:"control_plane" yaml:"control_plane"`
	Refresh      EdgeRefreshConf      `mapstructure:"refresh"       yaml:"refresh,omitempty"`
	// LongContextThresholdTokens is the input-token estimate at or above which
	// a request is classified as long-context for admission policy.
	LongContextThresholdTokens int `mapstructure:"long_context_threshold_tokens" yaml:"long_context_threshold_tokens,omitempty"`
	// ProviderPool is the canonical, shared queue policy for every provider
	// candidate in the pool. See EdgeProviderPoolConf for semantic details.
	ProviderPool EdgeProviderPoolConf `mapstructure:"provider_pool" yaml:"provider_pool"`
	Nodes        []NodeDefinition     `mapstructure:"nodes" yaml:"nodes"`
	// Models is the top-level model catalog.  Each entry defines a canonical
	// routing key (ID) and its provider-pool mapping.  When set it takes
	// precedence over the legacy openai.model_routes for runtime dispatch.
	Models []ModelCatalogEntry `mapstructure:"models" yaml:"models,omitempty"`
}

// EdgeInfo carries this edge instance's stable identity for loading and logging.
// It is not used for Control Plane registration.
type EdgeInfo struct {
	ID   string `mapstructure:"id"   yaml:"id"`
	Name string `mapstructure:"name" yaml:"name"`
}

// EdgeServerConf configures the Edge HTTP listen surface.
type EdgeServerConf struct {
	Listen        string `mapstructure:"listen"         yaml:"listen"`
	AdvertiseHost string `mapstructure:"advertise_host" yaml:"advertise_host"`
}

// EdgeBootstrapConf configures the Node bootstrap artifact HTTP server.
type EdgeBootstrapConf struct {
	ArtifactBaseURL string `mapstructure:"artifact_base_url" yaml:"artifact_base_url"`
	Listen          string `mapstructure:"listen"            yaml:"listen"`
	ArtifactDir     string `mapstructure:"artifact_dir"      yaml:"artifact_dir"`
}

// EdgeControlPlaneConf holds the outbound connector settings for the
// Control Plane-Edge wire. When Enabled is false or WireAddr is empty the
// connector is a no-op and existing Edge behaviour is unaffected.
type EdgeControlPlaneConf struct {
	Enabled              bool   `mapstructure:"enabled"               yaml:"enabled"`
	WireAddr             string `mapstructure:"wire_addr"             yaml:"wire_addr"`
	ReconnectIntervalSec int    `mapstructure:"reconnect_interval_sec" yaml:"reconnect_interval_sec"`
}

// EdgeRefreshConf configures the Edge-local refresh admin HTTP server.
// When Enabled is false (default) the admin server is not started and
// config refresh is not available without a restart.
type EdgeRefreshConf struct {
	Enabled bool   `mapstructure:"enabled" yaml:"enabled"`
	Listen  string `mapstructure:"listen"  yaml:"listen"`
}

// NodeDefinition is the edge-side record for a pre-registered node.
type NodeDefinition struct {
	ID        string             `mapstructure:"id"         yaml:"id"` // stable node identity; if empty, a UUID v4 is auto-assigned (dev fallback only)
	Alias     string             `mapstructure:"alias"      yaml:"alias"`
	Token     string             `mapstructure:"token"      yaml:"token"`
	AgentKind string             `mapstructure:"agent_kind" yaml:"agent_kind"` // generic-node (default)
	Adapters  AdaptersConf       `mapstructure:"adapters"   yaml:"adapters"`
	Providers []NodeProviderConf `mapstructure:"providers" yaml:"providers,omitempty"`
	Runtime   RuntimeConf        `mapstructure:"runtime"    yaml:"runtime"`
}

// OpenAIRouteEntry maps an external model id to an internal adapter/target routing.
// Fields not set here fall back to the top-level EdgeOpenAIConf defaults.
type OpenAIRouteEntry struct {
	Model             string `mapstructure:"model"              yaml:"model"`
	NodeRef           string `mapstructure:"node"               yaml:"node,omitempty"`
	Adapter           string `mapstructure:"adapter"            yaml:"adapter,omitempty"`
	Target            string `mapstructure:"target"             yaml:"target"`
	SessionID         string `mapstructure:"session_id"         yaml:"session_id,omitempty"`
	TimeoutSec        int    `mapstructure:"timeout_sec"        yaml:"timeout_sec,omitempty"`
	MaxQueue          int    `mapstructure:"max_queue"          yaml:"max_queue,omitempty"`
	QueueTimeoutMS    int    `mapstructure:"queue_timeout_ms"   yaml:"queue_timeout_ms,omitempty"`
	WorkspaceRequired bool   `mapstructure:"workspace_required" yaml:"workspace_required,omitempty"`
}

// EdgeOpenAIConf configures the OpenAI-compatible input surface.
type EdgeOpenAIConf struct {
	Enabled            bool                       `mapstructure:"enabled"              yaml:"enabled"`
	Listen             string                     `mapstructure:"listen"               yaml:"listen"`
	BearerToken        string                     `mapstructure:"bearer_token"         yaml:"bearer_token"`
	PrincipalTokens    []OpenAIPrincipalTokenConf `mapstructure:"principal_tokens"     yaml:"principal_tokens,omitempty"`
	ProviderAuth       EdgeOpenAIProviderAuthConf `mapstructure:"provider_auth"        yaml:"provider_auth,omitempty"`
	NodeRef            string                     `mapstructure:"node"                 yaml:"node"`
	Adapter            string                     `mapstructure:"adapter"              yaml:"adapter"`
	Target             string                     `mapstructure:"target"               yaml:"target"`
	Models             []string                   `mapstructure:"models"               yaml:"models"`
	ModelRoutes        []OpenAIRouteEntry         `mapstructure:"model_routes"         yaml:"model_routes,omitempty"`
	SessionID          string                     `mapstructure:"session_id"           yaml:"session_id"`
	TimeoutSec         int                        `mapstructure:"timeout_sec"          yaml:"timeout_sec"`
	StrictOutput       bool                       `mapstructure:"strict_output"        yaml:"strict_output"`
	StrictStreamBuffer bool                       `mapstructure:"strict_stream_buffer" yaml:"strict_stream_buffer"`
}

// EdgeOpenAIProviderAuthConf configures request-time provider token forwarding.
// It only describes which caller header to forward and never stores raw token
// values in config.
type EdgeOpenAIProviderAuthConf struct {
	Enabled      bool   `mapstructure:"enabled"       yaml:"enabled,omitempty"`
	FromHeader   string `mapstructure:"from_header"   yaml:"from_header,omitempty"`
	TargetHeader string `mapstructure:"target_header" yaml:"target_header,omitempty"`
	Scheme       string `mapstructure:"scheme"        yaml:"scheme,omitempty"`
	Required     bool   `mapstructure:"required"      yaml:"required,omitempty"`
}

// OpenAIPrincipalTokenConf maps a hashed OpenAI-compatible bearer token to the
// IOP bearer-token-operation identity it authenticates as. Raw tokens are
// never stored in config; only the SHA-256 hash is persisted.
type OpenAIPrincipalTokenConf struct {
	TokenRef        string `mapstructure:"token_ref"         yaml:"token_ref"`
	TokenHashSHA256 string `mapstructure:"token_hash_sha256" yaml:"token_hash_sha256"`
	PrincipalRef    string `mapstructure:"principal_ref"     yaml:"principal_ref"`
	PrincipalAlias  string `mapstructure:"principal_alias"   yaml:"principal_alias,omitempty"`
}

// EdgeA2AConf configures the A2A input surface.
type EdgeA2AConf struct {
	Enabled     bool   `mapstructure:"enabled"      yaml:"enabled"`
	Listen      string `mapstructure:"listen"       yaml:"listen"`
	Path        string `mapstructure:"path"         yaml:"path"`
	NodeRef     string `mapstructure:"node"         yaml:"node"`
	Adapter     string `mapstructure:"adapter"      yaml:"adapter"`
	Target      string `mapstructure:"target"       yaml:"target"`
	SessionID   string `mapstructure:"session_id"   yaml:"session_id"`
	TimeoutSec  int    `mapstructure:"timeout_sec"  yaml:"timeout_sec"`
	BearerToken string `mapstructure:"bearer_token" yaml:"bearer_token"`
}

// EdgeConsoleConf configures the ops console target.
type EdgeConsoleConf struct {
	Adapter    string `mapstructure:"adapter"     yaml:"adapter"`
	Target     string `mapstructure:"target"      yaml:"target"`
	Agent      string `mapstructure:"agent"       yaml:"agent"` // legacy alias for target
	Model      string `mapstructure:"model"       yaml:"model"` // legacy alias for target
	SessionID  string `mapstructure:"session_id"  yaml:"session_id"`
	Background bool   `mapstructure:"background"  yaml:"background"`
	TimeoutSec int    `mapstructure:"timeout_sec" yaml:"timeout_sec"`
}

// ResolveTarget returns the resolved console target, preferring the explicit
// Target field, then the legacy Agent alias, then the legacy Model alias.
func (c EdgeConsoleConf) ResolveTarget() string {
	if c.Target != "" {
		return c.Target
	}
	if c.Agent != "" {
		return c.Agent
	}
	return c.Model
}

// ResolveAgent is kept for callers still using the legacy console.agent name.
func (c EdgeConsoleConf) ResolveAgent() string {
	return c.ResolveTarget()
}

// TLSConf configures mTLS for the Edge server surface.
type TLSConf struct {
	Enabled bool   `mapstructure:"enabled" yaml:"enabled"`
	Cert    string `mapstructure:"cert"    yaml:"cert"`
	Key     string `mapstructure:"key"     yaml:"key"`
	CA      string `mapstructure:"ca"      yaml:"ca"`
}

// LoggingConf configures structured logging output.
type LoggingConf struct {
	Level  string `mapstructure:"level"  yaml:"level"`
	Pretty bool   `mapstructure:"pretty" yaml:"pretty"`
	Path   string `mapstructure:"path"   yaml:"path"`
}

// MetricsConf configures the Prometheus metrics HTTP port.
type MetricsConf struct {
	Port int `mapstructure:"port" yaml:"port"`
}

// SQLiteConf configures the SQLite backend DSN.
type SQLiteConf struct {
	DSN string `mapstructure:"dsn" yaml:"dsn"`
}

// NodeInfo carries a node's stable identity.
type NodeInfo struct {
	ID   string `mapstructure:"id"   yaml:"id"`
	Name string `mapstructure:"name" yaml:"name"`
}
