blob: 361ae2b132361aaf229901b983ac9bdaf35f8426 [file] [log] [blame]
package config
import (
"fmt"
"os"
)
// Config represents the complete configuration for KorAP MCP server
type Config struct {
// Server configuration
Server ServerConfig `yaml:"server" embed:""`
// OAuth2 authentication configuration
OAuth OAuthConfig `yaml:"oauth"`
// KorAP API configuration
KorAP KorAPConfig `yaml:"korap"`
// Logging configuration
Logging LoggingConfig `yaml:"logging"`
}
// ServerConfig represents server-specific configuration
type ServerConfig struct {
// Name is the server name (constant, not configurable)
Name string `yaml:"-"`
// Version is the server version (constant, not configurable)
Version string `yaml:"-"`
// ConfigFile is the path to the configuration file (handled by CLI layer)
ConfigFile string `yaml:"-"`
}
// KorAPConfig represents KorAP API configuration
type KorAPConfig struct {
// BaseURL is the KorAP server base URL
BaseURL string `yaml:"base_url" default:"https://korap.ids-mannheim.de" help:"KorAP server base URL"`
// APIVersion is the API version to use
APIVersion string `yaml:"api_version" default:"v1.0" help:"KorAP API version"`
// Timeout is the HTTP request timeout in seconds
Timeout int `yaml:"timeout" default:"30" help:"HTTP request timeout in seconds"`
// MaxRetries is the maximum number of retry attempts
MaxRetries int `yaml:"max_retries" default:"3" help:"Maximum number of retry attempts"`
}
// LoggingConfig represents logging configuration
type LoggingConfig struct {
// Level is the logging level (trace, debug, info, warn, error)
Level string `yaml:"level" default:"info" enum:"trace,debug,info,warn,error" help:"Logging level"`
// Format is the log format (json, text)
Format string `yaml:"format" default:"text" enum:"json,text" help:"Log output format"`
// File is the log file path (empty for stdout)
File string `yaml:"file" help:"Log file path (empty for stdout)"`
}
// DefaultConfig returns a default configuration
func DefaultConfig() *Config {
return &Config{
Server: ServerConfig{
// Name and Version are set by the CLI layer as constants
},
OAuth: *DefaultOAuthConfig(),
KorAP: KorAPConfig{
BaseURL: "https://korap.ids-mannheim.de",
APIVersion: "v1.0",
Timeout: 30,
MaxRetries: 3,
},
Logging: LoggingConfig{
Level: "info",
Format: "text",
},
}
}
// Validate validates the complete configuration
func (c *Config) Validate() error {
if err := c.OAuth.Validate(); err != nil {
return fmt.Errorf("oauth config validation failed: %w", err)
}
if err := c.KorAP.Validate(); err != nil {
return fmt.Errorf("korap config validation failed: %w", err)
}
if err := c.Logging.Validate(); err != nil {
return fmt.Errorf("logging config validation failed: %w", err)
}
return nil
}
// Validate validates KorAP configuration
func (k *KorAPConfig) Validate() error {
if k.BaseURL == "" {
return fmt.Errorf("base_url cannot be empty")
}
if k.APIVersion == "" {
return fmt.Errorf("api_version cannot be empty")
}
if k.Timeout <= 0 {
return fmt.Errorf("timeout must be positive")
}
if k.MaxRetries < 0 {
return fmt.Errorf("max_retries cannot be negative")
}
return nil
}
// Validate validates logging configuration
func (l *LoggingConfig) Validate() error {
validLevels := map[string]bool{
"trace": true,
"debug": true,
"info": true,
"warn": true,
"error": true,
}
if !validLevels[l.Level] {
return fmt.Errorf("invalid log level: %s", l.Level)
}
validFormats := map[string]bool{
"json": true,
"text": true,
}
if !validFormats[l.Format] {
return fmt.Errorf("invalid log format: %s", l.Format)
}
// Check if log file is writable if specified
if l.File != "" {
file, err := os.OpenFile(l.File, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
return fmt.Errorf("cannot write to log file %s: %w", l.File, err)
}
file.Close()
}
return nil
}
// GetKorAPEndpoint returns the full KorAP API endpoint URL
func (k *KorAPConfig) GetKorAPEndpoint() string {
return fmt.Sprintf("%s/api/%s", k.BaseURL, k.APIVersion)
}