//     Sofaraum client is the client software which collects statistics about
//     wifi devices nearby and then sends them to the Sofaraum Server.
//     Copyright (c) 2018.
//
//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
//
//     You should have received a copy of the GNU General Public License
//     along with this program.  If not, see <https://www.gnu.org/licenses/>.

package cmd

import (
	"fmt"
	"os"
	"strings"

	"github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "sofa",
	Short: "The sofaraum client which collects statistics and sends them to a sofaraum server",
	Long: `The sofaraum client which collects statistics about nearby wifi devices and sends them to a sofaraum server.

Find more information on sofaraum.de`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Global flag
	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.sofad.yaml or the directory of the binary)")
	rootCmd.PersistentFlags().StringP("serverurl", "s", "", "The server url where the client will send the data to")
	viper.BindPFlag("server.serverurl", rootCmd.Flags().Lookup("serverurl"))
	rootCmd.PersistentFlags().StringP("privatekey", "k", "", "The location of the private key which will be used to authenticate against the server")
	viper.BindPFlag("server.privatekey", rootCmd.Flags().Lookup("privatekey"))
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cfgFile)
	} else {
		// Find home directory.
		home, err := homedir.Dir()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		viper.AddConfigPath(home)
		viper.SetConfigName(".sofad")
	}

	viper.AddConfigPath(".")
	viper.SetConfigName("sofad.yml")

	// Init checking for environment variables
	viper.SetEnvPrefix("sofa")
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	viper.AutomaticEnv()

	// Set default configs
	// Daemon
	viper.SetDefault("daemon.csvlocation", "")
	viper.SetDefault("daemon.wifidevice", "wlan0")
	viper.SetDefault("daemon.enableemetricsendpoint", false) // Enable a /metrics endpoint for prometheus to get statistics
	viper.SetDefault("daemon.metricsinterface", ":2112")
	// Server
	viper.SetDefault("server.url", "")
	viper.SetDefault("server.privatekey", "")

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
