package app

import (
	"context"
	"fmt"

	"coopcloud.tech/abra/cli/internal"
	"coopcloud.tech/abra/pkg/autocomplete"
	"coopcloud.tech/abra/pkg/client"
	"coopcloud.tech/abra/pkg/config"
	containerPkg "coopcloud.tech/abra/pkg/container"
	"coopcloud.tech/abra/pkg/recipe"
	"coopcloud.tech/abra/pkg/service"
	"coopcloud.tech/abra/pkg/upstream/container"
	"github.com/docker/cli/cli/command"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

var targetPath string
var targetPathFlag = &cli.StringFlag{
	Name:        "target, t",
	Usage:       "Target path",
	Destination: &targetPath,
}

var appRestoreCommand = cli.Command{
	Name:      "restore",
	Aliases:   []string{"rs"},
	Usage:     "Restore an app backup",
	ArgsUsage: "<domain> <service>",
	Flags: []cli.Flag{
		internal.DebugFlag,
		internal.OfflineFlag,
		targetPathFlag,
	},
	Before:       internal.SubCommandBefore,
	BashComplete: autocomplete.AppNameComplete,
	Action: func(c *cli.Context) error {
		app := internal.ValidateApp(c)

		if err := recipe.EnsureExists(app.Recipe); err != nil {
			logrus.Fatal(err)
		}

		if !internal.Chaos {
			if err := recipe.EnsureIsClean(app.Recipe); err != nil {
				logrus.Fatal(err)
			}

			if !internal.Offline {
				if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
					logrus.Fatal(err)
				}
			}

			if err := recipe.EnsureLatest(app.Recipe); err != nil {
				logrus.Fatal(err)
			}
		}

		cl, err := client.New(app.Server)
		if err != nil {
			logrus.Fatal(err)
		}

		chosenService, err := service.GetServiceByLabel(context.Background(), cl, config.BackupbotLabel, internal.NoInput)
		if err != nil {
			logrus.Fatal(err)
		}

		logrus.Debugf("retrieved %s as backup enabled service", chosenService.Spec.Name)

		filters := filters.NewArgs()
		filters.Add("name", chosenService.Spec.Name)
		targetContainer, err := containerPkg.GetContainer(
			context.Background(),
			cl,
			filters,
			internal.NoInput,
		)
		if err != nil {
			logrus.Fatal(err)
		}

		execEnv := []string{fmt.Sprintf("SERVICE=%s", app.Domain)}
		if snapshot != "" {
			logrus.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot)
			execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot))
		}
		if targetPath != "" {
			logrus.Debugf("including TARGET=%s in backupbot exec invocation", targetPath)
			execEnv = append(execEnv, fmt.Sprintf("TARGET=%s", targetPath))
		}
		execBackupListOpts := types.ExecConfig{
			AttachStderr: true,
			AttachStdin:  true,
			AttachStdout: true,
			Cmd:          []string{"/usr/bin/backup", "--", "restore"},
			Detach:       false,
			Env:          execEnv,
			Tty:          true,
		}

		logrus.Debugf("running backup list on %s with exec config %v", targetContainer.ID, execBackupListOpts)

		// FIXME: avoid instantiating a new CLI
		dcli, err := command.NewDockerCli()
		if err != nil {
			logrus.Fatal(err)
		}

		if err := container.RunExec(dcli, cl, targetContainer.ID, &execBackupListOpts); err != nil {
			logrus.Fatal(err)
		}

		return nil
	},
}