package config

import (
	"flag"
	"fmt"

	"git.paulbsd.com/paulbsd/pki/utils"
	"github.com/go-acme/lego/v4/lego"
	"gopkg.in/ini.v1"
	"xorm.io/xorm"
)

// GetConfig fetch configuration
func (cfg *Config) GetConfig() error {
	var configfile string
	var debug bool
	var drop bool
	var port int
	var init bool

	flag.Usage = utils.Usage

	flag.StringVar(&configfile, "configfile", "pki.ini", "Configuration file to use with pki section")
	flag.IntVar(&port, "port", 8080, "Web service port to use")
	flag.BoolVar(&debug, "debug", false, "If debug logging must be enabled")
	flag.BoolVar(&drop, "drop", false, "If dropping tables must occur")
	flag.BoolVar(&init, "init", false, "If init of database must be done")

	flag.Parse()

	cfg.Switchs.Port = port
	cfg.Switchs.Debug = debug
	cfg.Switchs.Drop = drop
	cfg.Switchs.Init = init

	inicfg, err := ini.Load(configfile)
	if err != nil {
		return err
	}

	pkisection := inicfg.Section("pki")
	options := make(map[string]string)

	cfg.DbParams.DbHostname = pkisection.Key("db_hostname").MustString("localhost")
	cfg.DbParams.DbName = pkisection.Key("db_name").MustString("database")
	cfg.DbParams.DbUsername = pkisection.Key("db_username").MustString("username")
	cfg.DbParams.DbPassword = pkisection.Key("db_password").MustString("password")

	cfg.Options.HideBanner = pkisection.Key("hidebanner").MustBool(true)

	cfg.Init.Email = pkisection.Key("email").MustString("email@email.com")
	cfg.Init.Username = pkisection.Key("username").MustString("pki")
	cfg.Init.Password = pkisection.Key("password").MustString("P@ssw0rd!")

	cfg.ACME.Env = pkisection.Key("env").MustString("prod")
	cfg.ACME.MaxDaysBefore = pkisection.Key("maxdaysbefore").MustInt(0)

	options["ovhendpoint"] = pkisection.Key("ovhendpoint").MustString("ovh-eu")
	options["ovhak"] = pkisection.Key("ovhak").MustString("")
	options["ovhas"] = pkisection.Key("ovhas").MustString("")
	options["ovhck"] = pkisection.Key("ovhck").MustString("")

	options["pdnsapiurl"] = pkisection.Key("pdnsapiurl").MustString("")
	options["pdnsapikey"] = pkisection.Key("pdnsapikey").MustString("")

	cfg.ACME.ProviderOptions = options
	for key, value := range options {
		if value == "" {
			utils.Advice(fmt.Sprintf("Provider parameter %s not set", key))
		}
	}

	switch cfg.ACME.Env {
	case "prod":
		cfg.ACME.AuthURL = lego.LEDirectoryProduction
	case "staging":
		cfg.ACME.AuthURL = lego.LEDirectoryStaging
	default:
		cfg.ACME.AuthURL = lego.LEDirectoryStaging
	}

	return nil
}

// Config is the global config
type Config struct {
	Db       *xorm.Engine `json:"-"`
	DbParams struct {
		DbHostname string `json:"dbhostname"`
		DbName     string `json:"dbname"`
		DbUsername string `json:"dbusername"`
		DbPassword string `json:"dbpassword"`
	} `json:"dbparams"`
	Options struct {
		Version    string `json:"version"`
		HideBanner bool   `json:"hidebanner"`
	} `json:"-"`
	Switchs struct {
		Port   int  `json:"port"`
		NoFeed bool `json:"nofeed"`
		Debug  bool `json:"debug"`
		Drop   bool `json:"drop"`
		Init   bool `json:"init"`
	} `json:"-"`
	ACME struct {
		Env             string            `json:"env"`
		AuthURL         string            `json:"authurl"`
		ProviderOptions map[string]string `json:"provideroptions"`
		MaxDaysBefore   int               `json:"maxdaysbefore"`
	}
	Init struct {
		Email    string `json:"email"`
		Username string `json:"username"`
		Password string `json:"password"`
	} `json:"-"`
}
