blob: 361ae2b132361aaf229901b983ac9bdaf35f8426 [file] [log] [blame]
Akron90f65212025-06-12 14:32:55 +02001package config
2
3import (
4 "fmt"
5 "os"
6)
7
8// Config represents the complete configuration for KorAP MCP server
9type Config struct {
10 // Server configuration
11 Server ServerConfig `yaml:"server" embed:""`
12
13 // OAuth2 authentication configuration
14 OAuth OAuthConfig `yaml:"oauth"`
15
16 // KorAP API configuration
17 KorAP KorAPConfig `yaml:"korap"`
18
19 // Logging configuration
20 Logging LoggingConfig `yaml:"logging"`
21}
22
23// ServerConfig represents server-specific configuration
24type ServerConfig struct {
25 // Name is the server name (constant, not configurable)
26 Name string `yaml:"-"`
27
28 // Version is the server version (constant, not configurable)
29 Version string `yaml:"-"`
30
31 // ConfigFile is the path to the configuration file (handled by CLI layer)
32 ConfigFile string `yaml:"-"`
33}
34
35// KorAPConfig represents KorAP API configuration
36type KorAPConfig struct {
37 // BaseURL is the KorAP server base URL
38 BaseURL string `yaml:"base_url" default:"https://korap.ids-mannheim.de" help:"KorAP server base URL"`
39
40 // APIVersion is the API version to use
41 APIVersion string `yaml:"api_version" default:"v1.0" help:"KorAP API version"`
42
43 // Timeout is the HTTP request timeout in seconds
44 Timeout int `yaml:"timeout" default:"30" help:"HTTP request timeout in seconds"`
45
46 // MaxRetries is the maximum number of retry attempts
47 MaxRetries int `yaml:"max_retries" default:"3" help:"Maximum number of retry attempts"`
48}
49
50// LoggingConfig represents logging configuration
51type LoggingConfig struct {
52 // Level is the logging level (trace, debug, info, warn, error)
53 Level string `yaml:"level" default:"info" enum:"trace,debug,info,warn,error" help:"Logging level"`
54
55 // Format is the log format (json, text)
56 Format string `yaml:"format" default:"text" enum:"json,text" help:"Log output format"`
57
58 // File is the log file path (empty for stdout)
59 File string `yaml:"file" help:"Log file path (empty for stdout)"`
60}
61
62// DefaultConfig returns a default configuration
63func DefaultConfig() *Config {
64 return &Config{
65 Server: ServerConfig{
66 // Name and Version are set by the CLI layer as constants
67 },
68 OAuth: *DefaultOAuthConfig(),
69 KorAP: KorAPConfig{
70 BaseURL: "https://korap.ids-mannheim.de",
71 APIVersion: "v1.0",
72 Timeout: 30,
73 MaxRetries: 3,
74 },
75 Logging: LoggingConfig{
76 Level: "info",
77 Format: "text",
78 },
79 }
80}
81
82// Validate validates the complete configuration
83func (c *Config) Validate() error {
84 if err := c.OAuth.Validate(); err != nil {
85 return fmt.Errorf("oauth config validation failed: %w", err)
86 }
87
88 if err := c.KorAP.Validate(); err != nil {
89 return fmt.Errorf("korap config validation failed: %w", err)
90 }
91
92 if err := c.Logging.Validate(); err != nil {
93 return fmt.Errorf("logging config validation failed: %w", err)
94 }
95
96 return nil
97}
98
99// Validate validates KorAP configuration
100func (k *KorAPConfig) Validate() error {
101 if k.BaseURL == "" {
102 return fmt.Errorf("base_url cannot be empty")
103 }
104
105 if k.APIVersion == "" {
106 return fmt.Errorf("api_version cannot be empty")
107 }
108
109 if k.Timeout <= 0 {
110 return fmt.Errorf("timeout must be positive")
111 }
112
113 if k.MaxRetries < 0 {
114 return fmt.Errorf("max_retries cannot be negative")
115 }
116
117 return nil
118}
119
120// Validate validates logging configuration
121func (l *LoggingConfig) Validate() error {
122 validLevels := map[string]bool{
123 "trace": true,
124 "debug": true,
125 "info": true,
126 "warn": true,
127 "error": true,
128 }
129
130 if !validLevels[l.Level] {
131 return fmt.Errorf("invalid log level: %s", l.Level)
132 }
133
134 validFormats := map[string]bool{
135 "json": true,
136 "text": true,
137 }
138
139 if !validFormats[l.Format] {
140 return fmt.Errorf("invalid log format: %s", l.Format)
141 }
142
143 // Check if log file is writable if specified
144 if l.File != "" {
145 file, err := os.OpenFile(l.File, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
146 if err != nil {
147 return fmt.Errorf("cannot write to log file %s: %w", l.File, err)
148 }
149 file.Close()
150 }
151
152 return nil
153}
154
155// GetKorAPEndpoint returns the full KorAP API endpoint URL
156func (k *KorAPConfig) GetKorAPEndpoint() string {
157 return fmt.Sprintf("%s/api/%s", k.BaseURL, k.APIVersion)
158}