package app

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"

	"coopcloud.tech/abra/cli/internal"
	"coopcloud.tech/abra/pkg/config"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli/v2"
)

var backupAllServices bool
var backupAllServicesFlag = &cli.BoolFlag{
	Name:        "all",
	Value:       false,
	Destination: &backupAllServices,
	Aliases:     []string{"a"},
	Usage:       "Backup all services",
}

var appBackupCommand = &cli.Command{
	Name:      "backup",
	Usage:     "Backup an app",
	Aliases:   []string{"b"},
	Flags:     []cli.Flag{backupAllServicesFlag},
	ArgsUsage: "<service>",
	Action: func(c *cli.Context) error {
		app := internal.ValidateApp(c)

		if c.Args().Get(1) != "" && backupAllServices {
			internal.ShowSubcommandHelpAndError(c, errors.New("cannot use '<service>' and '--all' together"))
		}

		abraSh := path.Join(config.ABRA_DIR, "apps", app.Type, "abra.sh")
		if _, err := os.Stat(abraSh); err != nil {
			if os.IsNotExist(err) {
				logrus.Fatalf("'%s' does not exist?", abraSh)
			}
			logrus.Fatal(err)
		}

		sourceCmd := fmt.Sprintf("source %s", abraSh)

		execCmd := "abra_backup"
		if !backupAllServices {
			serviceName := c.Args().Get(1)
			if serviceName == "" {
				internal.ShowSubcommandHelpAndError(c, errors.New("no service(s) target provided"))
			}
			execCmd = fmt.Sprintf("abra_backup_%s", serviceName)
		}

		bytes, err := ioutil.ReadFile(abraSh)
		if err != nil {
			logrus.Fatal(err)
		}
		if !strings.Contains(string(bytes), execCmd) {
			logrus.Fatalf("%s doesn't have a '%s' function", app.Type, execCmd)
		}

		sourceAndExec := fmt.Sprintf("%s; %s", sourceCmd, execCmd)
		cmd := exec.Command("bash", "-c", sourceAndExec)
		output, err := cmd.Output()
		if err != nil {
			logrus.Fatal(err)
		}

		fmt.Print(string(output))

		return nil
	},
}