package config

import (
	"github.com/UpmeshLTD/urus-aio/infrastructure/config"
	"github.com/UpmeshLTD/urus-aio/infrastructure/enums"
	"github.com/spf13/viper"
)

type configImpl struct {
	viper        *viper.Viper
	systemConfig *SystemConfig
}

type SystemConfig struct {
	App         App         `mapstructure:",squash"`
	Database    Database    `mapstructure:",squash"`
	GRPC        GRPC        `mapstructure:",squash"`
	HTTP        HTTP        `mapstructure:",squash"`
	Auth        Auth        `mapstructure:",squash"`
	CartService CartService `mapstructure:",squash"`
	Swagger     Swagger     `mapstructure:",squash"`
}

//go:generate mockery --name=ISystemConfig --inpackage --case=snake
type Config interface {
	GetAppConfig() App
	GetDatabaseConfig() Database
	GetGRPCConfig() GRPC
	GetHTTPConfig() HTTP
	GetAuthConfig() Auth
	GetCartServiceConfig() CartService
	GetSwaggerConfig() Swagger
	IsDevelopment() bool
}

func NewConfig() (Config, error) {
	cfg := &configImpl{
		viper: viper.New(),
	}
	systemCfg := &SystemConfig{}
	cfg.setDefaultConfig()
	res, err := config.LoadConfig(cfg.viper, systemCfg)
	if err != nil {
		return nil, err
	}
	return &configImpl{
		systemConfig: res.(*SystemConfig),
	}, nil
}

func (c *configImpl) setDefaultConfig() {
	c.setDefaultAppConfig()
	c.setDefaultDatabaseConfig()
	c.setDefaultGRPCConfig()
	c.setDefaultHTTPConfig()
	c.setDefaultAuthConfig()
	c.setDefaultCartServiceConfig()
}

func (c *configImpl) IsDevelopment() bool {
	return c.GetAppConfig().Environment == enums.EnvDevelopment
}
