package config import ( "context" coreio "forge.lthn.ai/core/go-io" coreerr "forge.lthn.ai/core/go-log" core "forge.lthn.ai/core/go/pkg/core" ) // Service wraps Config as a framework service with lifecycle support. type Service struct { *core.ServiceRuntime[ServiceOptions] config *Config } // ServiceOptions holds configuration for the config service. type ServiceOptions struct { // Path overrides the default config file path. Path string // EnvPrefix overrides the default environment variable prefix. EnvPrefix string // Medium overrides the default storage medium. Medium coreio.Medium } // NewConfigService creates a new config service factory for the Core framework. // Register it with core.WithService(config.NewConfigService). func NewConfigService(c *core.Core) (any, error) { svc := &Service{ ServiceRuntime: core.NewServiceRuntime(c, ServiceOptions{}), } return svc, nil } // OnStartup loads the configuration file during application startup. func (s *Service) OnStartup(_ context.Context) error { opts := s.Opts() var configOpts []Option if opts.Path != "" { configOpts = append(configOpts, WithPath(opts.Path)) } if opts.EnvPrefix != "" { configOpts = append(configOpts, WithEnvPrefix(opts.EnvPrefix)) } if opts.Medium != nil { configOpts = append(configOpts, WithMedium(opts.Medium)) } cfg, err := New(configOpts...) if err != nil { return coreerr.E("config.Service.OnStartup", "failed to create config", err) } s.config = cfg return nil } // Get retrieves a configuration value by key. func (s *Service) Get(key string, out any) error { if s.config == nil { return coreerr.E("config.Service.Get", "config not loaded", nil) } return s.config.Get(key, out) } // Set stores a configuration value by key. func (s *Service) Set(key string, v any) error { if s.config == nil { return coreerr.E("config.Service.Set", "config not loaded", nil) } return s.config.Set(key, v) } // Commit persists any configuration changes to disk. func (s *Service) Commit() error { if s.config == nil { return coreerr.E("config.Service.Commit", "config not loaded", nil) } return s.config.Commit() } // LoadFile merges a configuration file into the central configuration. func (s *Service) LoadFile(m coreio.Medium, path string) error { if s.config == nil { return coreerr.E("config.Service.LoadFile", "config not loaded", nil) } return s.config.LoadFile(m, path) } // Ensure Service implements core.Config and Startable at compile time. var ( _ core.Config = (*Service)(nil) _ core.Startable = (*Service)(nil) )