Files
nannyagent/internal/config/config.go
2025-10-25 12:39:48 +02:00

132 lines
2.9 KiB
Go

package config
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/joho/godotenv"
)
type Config struct {
// Supabase Configuration
SupabaseProjectURL string
// Edge Function Endpoints (auto-generated from SupabaseProjectURL)
DeviceAuthURL string
AgentAuthURL string
// Agent Configuration
TokenPath string
MetricsInterval int
// Debug/Development
Debug bool
}
var DefaultConfig = Config{
TokenPath: "./token.json",
MetricsInterval: 30,
Debug: false,
}
// LoadConfig loads configuration from environment variables and .env file
func LoadConfig() (*Config, error) {
config := DefaultConfig
// Try to load .env file from current directory or parent directories
envFile := findEnvFile()
if envFile != "" {
if err := godotenv.Load(envFile); err != nil {
fmt.Printf("Warning: Could not load .env file from %s: %v\n", envFile, err)
} else {
fmt.Printf("Loaded configuration from %s\n", envFile)
}
}
// Load from environment variables
if url := os.Getenv("SUPABASE_PROJECT_URL"); url != "" {
config.SupabaseProjectURL = url
}
if tokenPath := os.Getenv("TOKEN_PATH"); tokenPath != "" {
config.TokenPath = tokenPath
}
if debug := os.Getenv("DEBUG"); debug == "true" || debug == "1" {
config.Debug = true
}
// Auto-generate edge function URLs from project URL
if config.SupabaseProjectURL != "" {
config.DeviceAuthURL = fmt.Sprintf("%s/functions/v1/device-auth", config.SupabaseProjectURL)
config.AgentAuthURL = fmt.Sprintf("%s/functions/v1/agent-auth-api", config.SupabaseProjectURL)
}
// Validate required configuration
if err := config.Validate(); err != nil {
return nil, fmt.Errorf("configuration validation failed: %w", err)
}
return &config, nil
}
// Validate checks if all required configuration is present
func (c *Config) Validate() error {
var missing []string
if c.SupabaseProjectURL == "" {
missing = append(missing, "SUPABASE_PROJECT_URL")
}
if c.DeviceAuthURL == "" {
missing = append(missing, "DEVICE_AUTH_URL (or SUPABASE_PROJECT_URL)")
}
if c.AgentAuthURL == "" {
missing = append(missing, "AGENT_AUTH_URL (or SUPABASE_PROJECT_URL)")
}
if len(missing) > 0 {
return fmt.Errorf("missing required environment variables: %s", strings.Join(missing, ", "))
}
return nil
}
// findEnvFile looks for .env file in current directory and parent directories
func findEnvFile() string {
dir, err := os.Getwd()
if err != nil {
return ""
}
for {
envPath := filepath.Join(dir, ".env")
if _, err := os.Stat(envPath); err == nil {
return envPath
}
parent := filepath.Dir(dir)
if parent == dir {
break
}
dir = parent
}
return ""
}
// PrintConfig prints the current configuration (masking sensitive values)
func (c *Config) PrintConfig() {
if !c.Debug {
return
}
fmt.Println("Configuration:")
fmt.Printf(" Supabase Project URL: %s\n", c.SupabaseProjectURL)
fmt.Printf(" Metrics Interval: %d seconds\n", c.MetricsInterval)
fmt.Printf(" Debug: %v\n", c.Debug)
}