/*
Copyright © 2024 Brian Buller <brian@bullercodeworks.com>
*/
package cmd

import (
	"fmt"
	"os"

	"git.bullercodeworks.com/brian/keepass-cli/cli"
	"git.bullercodeworks.com/brian/keepass-cli/util"
	gap "github.com/muesli/go-app-paths"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"golang.design/x/clipboard"
)

// rootCmd represents the base command when called without any subcommands
var (
	Version    = "1.0"
	Build      = "1"
	Name       = "keepass-cli"
	configFile string
	ConfigDir  = ""
	program    cli.Program
	rootCmd    = &cobra.Command{
		Use:   "keepass-cli",
		Short: "CLI for Managing KeePass Files",
	}
)

// 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() {
	program = cli.Program{}
	err := program.Initialize()
	if err != nil {
		fmt.Println("Error:", err.Error())
		os.Exit(1)
	}

	err = rootCmd.Execute()
	if err != nil {
		fmt.Println("Error:", err.Error())
		os.Exit(1)
	}
}

func init() {
	err := clipboard.Init()
	if err != nil {
		os.Exit(1)
	}
	rootCmd.Version = Version
	initConfig()
}

func initConfig() {
	var firstDir string
	if configFile != "" {
		viper.SetConfigFile(configFile)
	} else {
		scope := gap.NewScope(gap.User, Name)
		dirs, err := scope.ConfigDirs()
		if err != nil {
			fmt.Println("Can't retrieve default config")
			os.Exit(1)
		}
		firstDir = dirs[0]
		for _, v := range dirs {
			viper.AddConfigPath(v)
		}
		viper.SetConfigName(Name)
		viper.SetConfigType("yaml")
	}
	configName := fmt.Sprintf("%s.yaml", Name)
	var createConfig bool
	ConfigDir = fmt.Sprintf("%s%s", firstDir, string(os.PathSeparator))
	configPath := fmt.Sprintf("%s%s", ConfigDir, configName)
	if err := viper.ReadInConfig(); err != nil {
		createConfig = true
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println("Config file not found.")
		} else {
			fmt.Println("Config file found, but some other error occurred.")
			fmt.Println(err)
		}
	}
	if createConfig {
		_, err := os.Stat(firstDir)
		if os.IsNotExist(err) {
			err := os.Mkdir(firstDir, 0755)
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
		}
		if err = viper.WriteConfigAs(configPath); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}
	db := viper.GetString("database")
	if db == "" {
		db = util.PromptUserTrimmed("Path to KeePass Database:")
		viper.Set("database", db)
	}
	viper.WriteConfig()
}
