package main

import (
	"bufio"
	"context"
	"os"
	"sort"
	"strconv"
	"strings"

	"github.com/packethost/packngo"
	"github.com/spf13/cobra"
	"k8s.io/klog/v2"

	"source.monogon.dev/cloud/shepherd/equinix/wrapngo"
	clicontext "source.monogon.dev/metropolis/cli/pkg/context"
)

var yoinkCmd = &cobra.Command{
	Use: "yoink",
	Long: `This moves a specified amount of servers that match the given spec to a different metro.
While spec is a easy to find argument that matches the equinix system spec e.g. w3amd.75xx24c.512.8160.x86, 
metro does not represent the public facing name. Instead it is the acutal datacenter name e.g. fr2"`,
	Short: "Move a server base on the spec from one to another project",
	Args:  cobra.NoArgs,
	Run:   doYoink,
}

func init() {
	yoinkCmd.Flags().Int("count", 1, "how many machines should be moved")
	yoinkCmd.Flags().String("equinix_source_project", "", "from which project should the machine be yoinked")
	yoinkCmd.Flags().String("equinix_target_project", "", "to which project should the machine be moved")
	yoinkCmd.Flags().String("spec", "", "which device spec should be moved")
	yoinkCmd.Flags().String("metro", "", "to which metro should be moved")
	rootCmd.AddCommand(yoinkCmd)
}

func doYoink(cmd *cobra.Command, args []string) {
	srcProject, err := cmd.Flags().GetString("equinix_source_project")
	if err != nil {
		klog.Exitf("flag: %v", err)
	}

	dstProject, err := cmd.Flags().GetString("equinix_target_project")
	if err != nil {
		klog.Exitf("flag: %v", err)
	}

	if srcProject == "" || dstProject == "" {
		klog.Exitf("missing project flags")
	}

	count, err := cmd.Flags().GetInt("count")
	if err != nil {
		klog.Exitf("flag: %v", err)
	}

	spec, err := cmd.Flags().GetString("spec")
	if err != nil {
		klog.Exitf("flag: %v", err)
	}

	if spec == "" {
		klog.Exitf("missing spec flag")
	}

	metro, err := cmd.Flags().GetString("metro")
	if err != nil {
		klog.Exitf("flag: %v", err)
	}

	if metro == "" {
		klog.Exitf("missing metro flag")
	}

	ctx := clicontext.WithInterrupt(context.Background())
	api := wrapngo.New(&c)

	klog.Infof("Listing reservations for %q", srcProject)
	reservations, err := api.ListReservations(ctx, srcProject)
	if err != nil {
		klog.Exitf("Failed to list reservations: %v", err)
	}

	type configDC struct {
		config string
		dc     string
	}
	mtypes := make(map[configDC]int)

	var matchingReservations []packngo.HardwareReservation
	reqType := configDC{config: strings.ToLower(args[0]), dc: strings.ToLower(args[1])}

	klog.Infof("Got %d reservations", len(reservations))
	for _, r := range reservations {
		curType := configDC{config: strings.ToLower(r.Plan.Name), dc: strings.ToLower(r.Facility.Metro.Code)}

		mtypes[curType]++
		if curType == reqType {
			matchingReservations = append(matchingReservations, r)
		}
	}

	klog.Infof("Found the following configurations:")
	for dc, c := range mtypes {
		klog.Infof("%s | %s | %d", dc.dc, dc.config, c)
	}

	if len(matchingReservations) == 0 {
		klog.Exitf("Configuration not found: %s - %s", reqType.dc, reqType.config)
	}

	if len(matchingReservations)-count < 0 {
		klog.Exitf("Not enough machines with matching configuration found ")
	}

	// prefer hosts that are not deployed
	sort.Slice(matchingReservations, func(i, j int) bool {
		return matchingReservations[i].Device == nil && matchingReservations[j].Device != nil
	})

	toMove := matchingReservations[:count]
	var toDelete []string
	for _, r := range toMove {
		if r.Device != nil {
			toDelete = append(toDelete, r.Device.Hostname)
		}
	}

	stdInReader := bufio.NewReader(os.Stdin)
	klog.Infof("Will move %d machines with spec %s in %s from %s to %s.", count, spec, metro, srcProject, dstProject)
	if len(toDelete) > 0 {
		klog.Warningf("Not enough free machines found. This will delete %d provisioned hosts! Hosts scheduled for deletion: ", len(toDelete))
		klog.Warningf("%s", strings.Join(toDelete, ", "))
		klog.Warningf("Please confirm by inputting in the number of machines that will be moved.")

		read, err := stdInReader.ReadString('\n')
		if err != nil {
			klog.Exitf("failed reading input: %v", err)
		}

		atoi, err := strconv.Atoi(read)
		if err != nil {
			klog.Exitf("failed parsing number: %v", err)
		}

		if atoi != len(toDelete) {
			klog.Exitf("Confirmation failed! Wanted \"%q\" got \"%d\"", len(toDelete), atoi)
		} else {
			klog.Infof("Thanks for the confirmation! continuing...")
		}
	}

	klog.Infof("Note: It can be normal for a device move to fail for project validation issues. This is a known issue and can be ignored")
	for _, r := range matchingReservations {
		if r.Device != nil {
			klog.Warningf("Deleting server %s (%s) on %s", r.Device.ID, r.Device.Hostname, r.ID)

			if err := api.DeleteDevice(ctx, r.Device.ID); err != nil {
				klog.Errorf("failed deleting device %s (%s): %v", r.Device.ID, r.Device.Hostname, err)
				continue
			}
		}

		_, err := api.MoveReservation(ctx, r.ID, dstProject)
		if err != nil {
			klog.Errorf("failed moving device %s: %v", r.ID, err)
		}
	}
}
