package setup

import (
	"fmt"

	"code.justin.tv/d8a/buddy/cmd/buddy-cli/data"
	"code.justin.tv/d8a/buddy/lib/clusters"
	"code.justin.tv/d8a/buddy/lib/clusters/clusterdb"
	"code.justin.tv/d8a/buddy/lib/store"

	"io/ioutil"
	"os"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

var writePasswordCmd = &cobra.Command{
	Use:   "write-password [cluster] [user]",
	Short: "Write a new password from a local secret file to the database",
	Long:  "Write a new password from a local secret file to the database",
	RunE: func(command *cobra.Command, args []string) error {
		if len(args) != 2 {
			return command.Usage()
		}

		clusterName := args[0]
		username := args[1]

		secretPath := fmt.Sprintf("/var/lib/sandstorm-agent/secrets/rds-buddy-%s-%s.sandstorm", clusterName, username)
		_, err := os.Stat(secretPath)
		if os.IsNotExist(err) {
			return errors.Wrap(err, fmt.Sprintf("secret file '%s' does not exist", secretPath))
		} else if err != nil {
			return errors.Wrap(err, fmt.Sprintf("error trying to file stat '%s'", secretPath))
		}

		secret, err := ioutil.ReadFile(secretPath)
		if err != nil {
			return errors.Wrap(err, fmt.Sprintf("could not read file '%s'", secretPath))
		}

		rdsInstance, err := data.RootData.LocateDataStore(false)
		if err != nil {
			return err
		}

		db, err := store.OpenDbConn(rdsInstance, data.RootData.SandstormClient())
		if err != nil {
			return err
		}

		data.RootData.ConfigFile().Cluster, err = store.GetClusters(db)
		if err != nil {
			return err
		}

		cluster := data.RootData.ConfigFile().GetCluster(clusterName)
		if cluster == nil {
			return fmt.Errorf("Could not find cluster %s", clusterName)
		}

		// We don't need to update the DB if the sandstorm secret already works
		_, err = clusterdb.OpenDbConnWithManualSecret(cluster, username, string(secret))
		if err == nil {
			return nil
		}

		if username == cluster.SuperUser {
			err = clusters.SetSuperUserPassword(data.RootData.RdsClient(), cluster, string(secret))
			if err != nil {
				return errors.Wrap(err, fmt.Sprintf("could not write superuser password for cluster %s", clusterName))
			}
		} else {
			clusterDb, err := clusterdb.OpenDbConn(cluster, data.RootData.SandstormClient(), cluster.SuperUser)
			if err != nil {
				return errors.Wrap(err, fmt.Sprintf("could not connect to cluster %s", clusterName))
			}

			err = clusterDb.SetUserPassword(username, string(secret))
			if err != nil {
				return errors.Wrap(err, fmt.Sprintf("could not write user password for %s on cluster %s", username, clusterName))
			}
		}

		return nil
	},
}

func init() {
	RootCmd.AddCommand(writePasswordCmd)
}
