package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"sync"
"github.com/BurntSushi/toml"
)
var lock = &sync.Mutex{}
type config struct {
Domain string
Mxdomain string
BoxesDir string
CertFile string
KeyFile string
LogLevel string
}
var confInstance *config
func GetConfig() *config {
if confInstance == nil {
lock.Lock()
defer lock.Unlock()
if confInstance == nil {
// initialize config instance
initializeConfig()
}
}
return confInstance
}
func initializeConfig() {
configFname := "config.toml"
configDir := os.Getenv("XDG_CONFIG_HOME")
if configDir == "" {
configDir = filepath.Join(os.Getenv("HOME"), ".config")
}
configDir = filepath.Join(configDir, "jums")
// Check for existence of file, create it with initial values if not found
if _, err := os.Stat(configDir); errors.Is(err, os.ErrNotExist) {
err = createConfigFile(configDir, configFname)
if err != nil {
panic(err)
}
}
confInstance = &config{}
_, err := toml.DecodeFile(filepath.Join(configDir, configFname), confInstance)
if err != nil {
// appropriate situation to panic since we flatly cannot proceed without the config
panic(err)
}
}
func createConfigFile(dir, fname string) error {
err := os.MkdirAll(dir, os.ModeDir)
if err != nil {
return fmt.Errorf("createConfigFile: %w", err)
}
cf, err := os.Create(filepath.Join(dir, fname))
if err != nil {
return fmt.Errorf("createConfigFile: %w", err)
}
c := config{
Domain: "localhost",
Mxdomain: "localhost",
BoxesDir: "~/.jums/mailboxes",
KeyFile: "",
CertFile: "",
LogLevel: "INFO",
}
err = toml.NewEncoder(cf).Encode(c)
if err != nil {
cf.Close()
return fmt.Errorf("createConfigFile: %w", err)
}
if err = cf.Sync(); err != nil {
return fmt.Errorf("createConfigFile: %w", err)
}
if err = cf.Close(); err != nil {
return fmt.Errorf("createConfigFile: %w", err)
}
return nil
}