package cmd

import (
	"context"
	"errors"
	"fmt"
	"runtime"

	"code.icod.de/dalu/gomanager/ent"
	"github.com/spf13/cobra"

	_ "github.com/mattn/go-sqlite3"
)

var (
	addUser             = ""
	addGroup            = ""
	addRootPath         = ""
	addBinaryPath       = ""
	addServiceName      = ""
	addBinaryTargetPath = ""
)

// addCmd represents the add command
var addCmd = &cobra.Command{
	Use:   "add",
	Short: "add a project for watching",
	Long: `add a project for watching
Example:
A project residing in /var/www/dalu/project
with a binary project at /var/www/dalu/project/project
and a systemd service named dalu-project.service
with the binary being owned by dalu:dalu

gomanager add \
--root-path="/var/www/dalu/project" \
--binary-path="project" \
--service-name="dalu-project.service" \
--user="dalu" \
--group="dalu"

let's assume we'd like to resulting binary to be moved to /usr/local/bin/project after building
we add
--binary-target-path="/usr/local/bin/project"

or with short notation:
gomanager add \
-r="/var/www/dalu/project" \
-b="project" \
-s="dalu-project.service" \
-u="dalu" \
-g="dalu"

with moving the compiled binary
-t="/usr/local/bin/project"

`,
	RunE: func(cmd *cobra.Command, args []string) error {
		runtime.GOMAXPROCS(1)
		client, err := ent.Open("sqlite3", fmt.Sprintf("file:%s?mode=rwc&cache=private&_fk=1", sqliteFilename))
		if err != nil {
			return fmt.Errorf("failed opening connection to sqlite: %v", err)
		}
		defer client.Close()

		if addUser == "" {
			return errors.New("user is empty")
		}
		if addGroup == "" {
			return errors.New("group is empty")
		}
		if addRootPath == "" {
			return errors.New("root-path is empty")
		}
		if addBinaryPath == "" {
			return errors.New("binary-path is empty")
		}
		if addServiceName == "" {
			return errors.New("service-name is empty")
		}

		p := client.Project.
			Create().
			SetUser(addUser).
			SetGroup(addGroup).
			SetRootPath(addRootPath).
			SetBinaryPath(addBinaryPath).
			SetServiceName(addServiceName)

		if addBinaryTargetPath != "" {
			p = p.SetMoveToTarget(true).SetBinaryTargetPath(addBinaryTargetPath)
		}
		project, e := p.Save(context.Background())
		if e != nil {
			return e
		}
		fmt.Printf("Saved project with ID: %d\n", project.ID)
		return nil
	},
}

func init() {
	rootCmd.AddCommand(addCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// addCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// addCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	addCmd.Flags().StringVarP(&addRootPath, "root-path", "r", "", "/var/www/code.icod.de/goroot")
	addCmd.Flags().StringVarP(&addServiceName, "service-name", "s", "", "mysystemd.service")
	addCmd.Flags().StringVarP(&addBinaryPath, "binary-path", "b", "", "gomanager or cmd/run/gomanager")
	addCmd.Flags().StringVarP(&addBinaryTargetPath, "binary-target-path", "t", "", "../binaries/gomanager-binary")
	addCmd.Flags().StringVarP(&addUser, "user", "u", "nginx", "www-data")
	addCmd.Flags().StringVarP(&addGroup, "group", "g", "nginx", "www-data")
}
