package configuration

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/config"
	"code.justin.tv/d8a/buddy/lib/store"
	"github.com/spf13/cobra"
)

var rolePairUpsert = &cobra.Command{
	Use:   "role-pair [cluster] [role name]",
	Short: "Add a new role pair to the cluster, if supported.",
	Long:  "Add a new role pair to the cluster, if supported.  Creates the users & sandstorm secrets if necessary.",
	RunE: func(command *cobra.Command, args []string) error {
		if len(data.ConfigureData.Args()) != 1 {
			return command.Usage()
		}

		storeDb := data.ConfigureData.StoreDB()
		rolePairName := data.ConfigureData.Args()[0]
		foundCluster := data.ConfigureData.FoundCluster()
		sandstormClient := data.ConfigureData.SandstormClient()

		clusterDb, err := clusterdb.OpenDbConn(foundCluster, sandstormClient, foundCluster.SuperUser)
		if err != nil {
			return err
		}

		//Make sure that rolepair_01 and rolepair_02 users exist
		err = clusters.EnsureChildUsers(storeDb, foundCluster, clusterDb, sandstormClient, rolePairName)
		if err != nil {
			return err
		}

		//Figure out whether the two users are set to LOGIN or NOLOGIN
		leftUser := fmt.Sprintf("%s_01", rolePairName)
		rightUser := fmt.Sprintf("%s_02", rolePairName)
		users, err := clusterDb.ClusterUsers()
		if err != nil {
			return err
		}

		leftUserLogin, ok := users[leftUser]
		if !ok {
			return fmt.Errorf("after setting up the role pair users, %s still doesn't exist", leftUser)
		}

		rightUserLogin, ok := users[rightUser]
		if !ok {
			return fmt.Errorf("after setting up the role pair users, %s still doesn't exist", rightUser)
		}

		if leftUserLogin && rightUserLogin {
			//If both users are active, try to disable the one not in use
			_, err = clusters.FixRoleKeys(clusterDb, &config.RolePair{
				Name: rolePairName,
				Users: []*config.User{
					&config.User{
						Name: leftUser,
					},
					&config.User{
						Name: rightUser,
					},
				},
			})
			if err != nil {
				return err
			}
		}

		//Verify that both users have no grants on themselves & inherit from the role
		err = clusters.EnsureUserPermissions(storeDb, clusterDb, foundCluster, sandstormClient, rolePairName, leftUser, rightUser)
		if err != nil {
			return err
		}

		//Write the role pair data to the buddy store
		return store.EnsureUserPair(storeDb, foundCluster, rolePairName)
	},
}

func init() {
	ConfigureCmd.AddCommand(rolePairUpsert)
}
