package cfgloader

import (
	"github.com/knadh/koanf"
	"log"
	"strings"

	"github.com/knadh/koanf/parsers/yaml"
	"github.com/knadh/koanf/providers/env"
	"github.com/knadh/koanf/providers/file"
	//"github.com/knadh/koanf/v2"
)

type Option struct {
	Prefix       string
	Delimiter    string
	Separator    string
	YamlFilePath string
	CallbackEnv  func(string) string
}

// defaultCallbackEnv processes environment variable keys based on provided prefix and separator
func defaultCallbackEnv(source, prefix, separator string) string {
	base := strings.ToLower(strings.TrimPrefix(source, prefix))
	return strings.ReplaceAll(base, separator, ".")
}

// Load function loads configuration from YAML file and environment variables based on provided options
func Load(options Option, config interface{}) error {
	k := koanf.New(options.Delimiter)

	// Load configuration from YAML file if provided
	if options.YamlFilePath != "" {
		if err := k.Load(file.Provider(options.YamlFilePath), yaml.Parser()); err != nil {
			log.Fatalf("Error loading config file: %v", err)
			return err
		}
	}

	// Define callback function for environment variables
	callback := options.CallbackEnv
	if callback == nil {
		// Set default callback using the prefix and separator from options
		callback = func(source string) string {
			return defaultCallbackEnv(source, options.Prefix, options.Separator)
		}
	}

	// Load environment variables with the specified prefix and callback
	if err := k.Load(env.Provider(options.Prefix, options.Delimiter, callback), nil); err != nil {
		log.Fatalf("Error loading environment variables: %v", err)
		return err
	}

	// Unmarshal into provided config structure (passing address)
	if err := k.Unmarshal("", &config); err != nil {
		log.Fatalf("Error unmarshalling config: %v", err)
		return err
	}

	return nil
}
