// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.package spec

package cmd

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

	"github.com/pingcap/tidb-cloud-manager/managerctl/cmd/templates"
	"github.com/pingcap/tidb-cloud-manager/managerctl/cmd/util"
)

var cmdFlags = CommandFlags{}

// CommandFlags are flags that used in all Commands
type CommandFlags struct {
	URL     string
	CfgFile string
}

// NewManagerCtlCommand create the `managerctl` command and its nested children
func NewManagerCtlCommand(cli util.Client) *cobra.Command {
	// Parent command to which all subcommands are added.
	cmds := &cobra.Command{
		Use:   "managerctl",
		Short: "managerctl controls the tidb cluster manager in k8s",
		Long: `managerctl controls the tidb cluster manager in k8s.

Need deploy tidb-controller-manager and tidb-cloud-manager before use managerctl.`,
		Run: util.RunHelp,
	}

	cmds.PersistentFlags().StringVarP(&cmdFlags.CfgFile, "config", "c", "", "config file (default is $HOME/.managerctl.yaml)")
	cmds.PersistentFlags().StringVarP(&cmdFlags.URL, "manager", "u", "", "cloud manager address")

	groups := templates.CommandGroups{
		{
			Message: "TiDB Cluster Manager Commands",
			Commands: []*cobra.Command{
				NewCmdCluster(cli),
				NewCmdPod(cli),
				NewCmdJob(cli),
				NewCmdResetPasswd(cli),
				NewCmdBackup(cli),
			},
		},
		{
			Message: "k8s Cluster Manager Commands",
			Commands: []*cobra.Command{
				NewCmdGetNodes(cli),
			},
		},
	}
	groups.Add(cmds)

	filters := []string{"options"}
	templates.ActsAsRootCommand(cmds, filters, groups...)
	cmds.AddCommand(NewCmdOptions())

	return cmds
}

func init() {
	cobra.OnInitialize(initConfig)
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cmdFlags.CfgFile != "" {
		// Use config file from the flag.
		viper.SetConfigFile(cmdFlags.CfgFile)
	} else {
		// Find home directory.
		home, err := homedir.Dir()
		util.CheckErr(err)

		// Search config in home directory with name ".managerctl" (without extension).
		viper.AddConfigPath(home)
		viper.SetConfigName(".managerctl")
	}

	viper.AutomaticEnv()

	// If a config file is found, read it in.
	err := viper.ReadInConfig()
	util.CheckErr(err)

	//fmt.Printf("Using config file: %s\n\n", viper.ConfigFileUsed())
	if cmdFlags.URL != "" {
		//preferentially use the value specified by the command line parameter
		return
	}
	if viper.GetString("manager") == "" {
		util.OutputErrorInfo("Not specified cloud manager address")
	}
	cmdFlags.URL = viper.GetString("manager")
}
