package config

import (
	"os"
	"path/filepath"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

// defaultDevRoot indicates the default project root. This can be overridden
// via the ENV variable CTMO_LOCALDEV_ROOT
const defaultDevRoot = "${HOME}/code/contiamo/dev"

const STunnelKeyFile = "config/pg-stunnel/cert/tls.key"
const STunnelCRTFile = "config/pg-stunnel/cert/tls.crt"

// cfg is the default config object
var cfg = Config{
	LocaldevRoot: defaultDevRoot,
}

// Config describes the localdev config file format in a type safe way
type Config struct {
	// LocaldevRoot is the abosolute path to the `contianmo/dev` clone on your machine.
	// This can be set in the $XDG_CONFIG_DIR/contiamo/localdev.yaml
	// or via the CTMO_LOCALDEVROOT environment variable.
	LocaldevRoot string `json:"localdevRoot,omitempty" yaml:"localdevRoot,omitempty"`
}

// LocaldevRoot returns the default localdev root path
func LocaldevRoot() string {
	return os.ExpandEnv(cfg.LocaldevRoot)
}

// configDir prints the user config path for contiamo.
func configDir() (string, error) {
	config, err := os.UserConfigDir()
	if err != nil {
		return "", err
	}
	configDir := filepath.Join(config, "contiamo")
	return configDir, nil
}

// STunnelEnabled checks if STunnel should be enabled by checking for the
// required Key and CRT files in the localdev config folder.
func STunnelEnabled() bool {
	_, err := os.Lstat(STunnelKeyFile)
	logrus.Debugf("stunnel lookup: %v", err)
	return err == nil
}

// lookup the pantehon redir docker image value, if it is set in the env.
func PantheonRedirImage() string {
	value, ok := os.LookupEnv("REDIR_IMAGE")
	if !ok {
		return "eu.gcr.io/dev-and-test-env/pantheon:redir"
	}

	return value
}

// DefaultConfigFile returns the name of the default config file location
func DefaultConfigFile() string {
	path, err := configDir()
	if err != nil {
		logrus.WithError(err).Debugf("can not determine the correct config path, using default: %s", defaultDevRoot)
		path = defaultDevRoot
	}

	path = os.ExpandEnv(path)
	return filepath.Join(path, "localdev.yaml")
}

// Setup initializes the config based on env variables and the config file, if it exists.
// The resulting config is then available in the default cfg value.
func Setup() error {
	path, err := configDir()
	if err != nil {
		return err
	}
	viper.AddConfigPath(path)

	logrus.Debugf("config path: %q", path)

	viper.SetDefault("localdevRoot", defaultDevRoot)

	viper.SetEnvPrefix("ctmo")
	viper.AutomaticEnv()

	viper.SetConfigName("localdev")
	viper.SetConfigType("yaml")

	err = viper.MergeInConfig()
	if err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			logrus.Debug(err)
		} else {
			return err
		}
	}

	configSrc := viper.ConfigFileUsed()
	logrus.Debugf("using config file at: %q", configSrc)

	return viper.Unmarshal(&cfg)
}
