package updatealiases

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"os"
	"text/tabwriter"

	"gitlab.com/gitlab-org/fleeting/fleeting-artifact/pkg/client"
)

type updateAliasesCmd struct {
	fs *flag.FlagSet

	dryrun bool
}

func New() *updateAliasesCmd {
	c := &updateAliasesCmd{}
	c.fs = flag.NewFlagSet("update-aliases", flag.ExitOnError)

	c.fs.BoolVar(&c.dryrun, "dryrun", false, "dry run will not make changes and return exit code 1 if changes are needed")

	c.fs.Usage = func() {
		fmt.Fprintln(c.fs.Output(), c.fs.Name(), "[OPTIONS] NAME[:VERSION_CONSTRAINT]")
		fmt.Fprint(
			c.fs.Output(),
			"\n  Updates aliases for versions matching the version constraint provided.\n",
			"\n  This is also performed when releasing a new artifact, so is rarely required to be run manually.\n\n",
		)
		c.fs.PrintDefaults()
	}

	return c
}

func (cmd *updateAliasesCmd) Command() *flag.FlagSet {
	return cmd.fs
}

func (cmd *updateAliasesCmd) Execute(ctx context.Context) error {
	if len(cmd.fs.Args()) < 1 {
		return flag.ErrHelp
	}

	c, err := client.New()
	if err != nil {
		return fmt.Errorf("creating client: %w", err)
	}

	updates, err := c.UpdateAliases(ctx, cmd.fs.Arg(0), cmd.dryrun)

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
	for _, update := range updates {
		fmt.Fprintf(w, "%s\t=\t%s\n", update.Alias, update.Version)
	}
	w.Flush()

	if err != nil {
		return err
	}

	if len(updates) == 0 {
		return nil
	}

	if !cmd.dryrun {
		return nil
	}

	return errors.New("updates are required")
}
