package config

import (
	"git.haelnorr.com/h/golib/ezconf"
	"git.haelnorr.com/h/golib/hlog"
	"git.haelnorr.com/h/golib/hws"
	"git.haelnorr.com/h/golib/hwsauth"
	"git.haelnorr.com/h/oslstats/internal/db"
	"git.haelnorr.com/h/oslstats/internal/discord"
	"git.haelnorr.com/h/oslstats/pkg/oauth"
	"github.com/joho/godotenv"
	"github.com/pkg/errors"
)

type Config struct {
	DB      *db.Config
	HWS     *hws.Config
	HWSAuth *hwsauth.Config
	HLOG    *hlog.Config
	Discord *discord.Config
	OAuth   *oauth.Config
	Flags   *Flags
}

// Load the application configuration and get a pointer to the Config object
// If doconly is specified, only the loader will be returned
func GetConfig(flags *Flags) (*Config, *ezconf.ConfigLoader, error) {
	err := godotenv.Load(flags.EnvFile)
	if err != nil && flags.GenEnv == "" && !flags.EnvDoc {
		return nil, nil, errors.Wrap(err, "gotgodotenv.Load")
	}

	loader := ezconf.New()
	loader.RegisterIntegrations(
		hlog.NewEZConfIntegration(),
		hws.NewEZConfIntegration(),
		hwsauth.NewEZConfIntegration(),
		db.NewEZConfIntegration(),
		discord.NewEZConfIntegration(),
		oauth.NewEZConfIntegration(),
	)
	if err := loader.ParseEnvVars(); err != nil {
		return nil, nil, errors.Wrap(err, "loader.ParseEnvVars")
	}

	if flags.GenEnv != "" || flags.EnvDoc {
		return nil, loader, nil
	}

	if err := loader.LoadConfigs(); err != nil {
		return nil, nil, errors.Wrap(err, "loader.LoadConfigs")
	}

	hwscfg, ok := loader.GetConfig("hws")
	if !ok {
		return nil, nil, errors.New("HWS Config not loaded")
	}

	hwsauthcfg, ok := loader.GetConfig("hwsauth")
	if !ok {
		return nil, nil, errors.New("HWSAuth Config not loaded")
	}

	hlogcfg, ok := loader.GetConfig("hlog")
	if !ok {
		return nil, nil, errors.New("HLog Config not loaded")
	}

	dbcfg, ok := loader.GetConfig("db")
	if !ok {
		return nil, nil, errors.New("DB Config not loaded")
	}

	discordcfg, ok := loader.GetConfig("discord")
	if !ok {
		return nil, nil, errors.New("Dicord Config not loaded")
	}

	oauthcfg, ok := loader.GetConfig("oauth")
	if !ok {
		return nil, nil, errors.New("OAuth Config not loaded")
	}

	config := &Config{
		DB:      dbcfg.(*db.Config),
		HWS:     hwscfg.(*hws.Config),
		HWSAuth: hwsauthcfg.(*hwsauth.Config),
		HLOG:    hlogcfg.(*hlog.Config),
		Discord: discordcfg.(*discord.Config),
		OAuth:   oauthcfg.(*oauth.Config),
		Flags:   flags,
	}

	return config, loader, nil
}
