package ipapi import ( "context" "log/slog" "git.eeqj.de/sneak/ipapi/internal/config" "git.eeqj.de/sneak/ipapi/internal/database" "git.eeqj.de/sneak/ipapi/internal/http" "git.eeqj.de/sneak/ipapi/internal/state" "go.uber.org/fx" ) // Options contains all dependencies for IPAPI. type Options struct { fx.In Config *config.Config Logger *slog.Logger State *state.Manager Database *database.Manager Server *http.Server } // IPAPI is the main application structure. type IPAPI struct { config *config.Config logger *slog.Logger state *state.Manager database *database.Manager server *http.Server } // New creates a new IPAPI instance with the given options. func New(opts Options) *IPAPI { return &IPAPI{ config: opts.Config, logger: opts.Logger, state: opts.State, database: opts.Database, server: opts.Server, } } // Start initializes and starts all components. func (i *IPAPI) Start(ctx context.Context) error { i.logger.Info("Starting IP API daemon", "port", i.config.Port, "state_dir", i.config.StateDir, ) // Initialize state if err := i.state.Initialize(ctx); err != nil { return err } // Download databases if needed if err := i.database.EnsureDatabases(ctx); err != nil { return err } // Start HTTP server return i.server.Start(ctx) } // Stop gracefully shuts down all components. func (i *IPAPI) Stop(ctx context.Context) error { i.logger.Info("Stopping IP API daemon") return i.server.Stop(ctx) }