package commands

import (
	"os"

	"git.ctrlz.es/mgdelacroix/craban/server"

	"github.com/rs/zerolog/log"
	"github.com/spf13/cobra"
)

func UserCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "user",
		Short: "User related commands",
	}

	cmd.AddCommand(
		CreateUserCmd(),
		ListUserCmd(),
		DeleteUserCmd(),
	)

	return cmd
}

func CreateUserCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "create",
		Short: "Create a new user",
		Args:  cobra.NoArgs,
		Run:   createUserCmdF,
	}

	cmd.Flags().StringP("username", "u", "", "the username of the new user")
	cmd.MarkFlagRequired("username")
	cmd.Flags().StringP("password", "p", "", "the password of the new user")
	cmd.MarkFlagRequired("password")
	cmd.Flags().StringP("name", "n", "", "the name of the new user")
	cmd.MarkFlagRequired("name")
	cmd.Flags().StringP("mail", "m", "", "the mail of the new user")
	cmd.MarkFlagRequired("mail")
	cmd.Flags().BoolP("admin", "a", false, "sets the new user as an admin")

	return cmd
}

func ListUserCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "list",
		Short: "List the users in the system",
		Args:  cobra.NoArgs,
		Run:   listUserCmdF,
	}
}

func DeleteUserCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "delete <username>",
		Short: "Delete a user by username",
		Args:  cobra.ExactArgs(1),
		Run:   deleteUserCmdF,
	}
}

func createUserCmdF(cmd *cobra.Command, _ []string) {
	username, _ := cmd.Flags().GetString("username")
	password, _ := cmd.Flags().GetString("password")
	name, _ := cmd.Flags().GetString("name")
	mail, _ := cmd.Flags().GetString("mail")
	admin, _ := cmd.Flags().GetBool("admin")

	config, _ := cmd.Flags().GetString("config")
	srv, err := server.NewServerWithConfigPath(config)
	if err != nil {
		log.Error().Err(err).Msg("cannot create server")
		os.Exit(1)
	}
	defer srv.Store.Close()

	user, err := srv.App.CreateUser(username, password, name, mail, admin)
	if err != nil {
		log.Error().Err(err).Msg("user couldn't be created")
		os.Exit(1)
	}

	log.Info().Str("username", user.Username).Msg("user successfully created")
}

func listUserCmdF(cmd *cobra.Command, _ []string) {
	config, _ := cmd.Flags().GetString("config")
	srv, err := server.NewServerWithConfigPath(config)
	if err != nil {
		log.Error().Err(err).Msg("cannot create server")
		os.Exit(1)
	}
	defer srv.Store.Close()

	users, err := srv.App.ListUsers()
	if err != nil {
		log.Error().Err(err).Msg("cannot get user list")
		os.Exit(1)
	}

	for _, user := range users {
		log.Info().Str("username", user.Username).Msg("")
	}
}

func deleteUserCmdF(cmd *cobra.Command, args []string) {
	config, _ := cmd.Flags().GetString("config")
	srv, err := server.NewServerWithConfigPath(config)
	if err != nil {
		log.Error().Err(err).Msg("cannot create server")
		os.Exit(1)
	}
	defer srv.Store.Close()

	if err := srv.App.DeleteUserByUsername(args[0]); err != nil {
		log.Error().Err(err).Str("username", args[0]).Msg("cannot delete user")
		os.Exit(1)
	}

	log.Info().Str("username", args[0]).Msg("user successfully deleted")
}
