package cli

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"path"

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

// downloadFile downloads a file brah
func downloadFile(filepath string, url string) (err error) {
	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer out.Close()

	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("bad status: %s", resp.Status)
	}

	_, err = io.Copy(out, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

// AutoCompleteCommand helps people set up auto-complete in their shells
var AutoCompleteCommand = &cli.Command{
	Name:    "autocomplete",
	Usage:   "Help set up shell autocompletion",
	Aliases: []string{"ac"},
	Description: `
This command helps set up autocompletion in your shell by downloading the
relevant autocompletion files and laying out what additional information must
be loaded.

Example:

    abra autocomplete bash

Supported shells are as follows:

		fizsh
		zsh
    bash
`,
	ArgsUsage: "<shell>",
	Action: func(c *cli.Context) error {
		shellType := c.Args().First()

		if shellType == "" {
			internal.ShowSubcommandHelpAndError(c, errors.New("no shell provided"))
		}

		supportedShells := map[string]bool{
			"bash":  true,
			"zsh":   true,
			"fizsh": true,
		}

		if _, ok := supportedShells[shellType]; !ok {
			logrus.Fatalf("%s is not a supported shell right now, sorry", shellType)
		}

		if shellType == "fizsh" {
			shellType = "zsh" // handled the same on the autocompletion side
		}

		autocompletionDir := path.Join(config.ABRA_DIR, "autocompletion")
		if err := os.Mkdir(autocompletionDir, 0644); err != nil {
			if !os.IsExist(err) {
				logrus.Fatal(err)
			}
			logrus.Debugf("'%s' already created, moving on...", autocompletionDir)
		}

		autocompletionFile := path.Join(config.ABRA_DIR, "autocompletion", shellType)
		if _, err := os.Stat(autocompletionFile); err != nil && os.IsNotExist(err) {
			url := fmt.Sprintf("https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/autocomplete/%s", shellType)
			logrus.Infof("fetching %s", url)
			if err := downloadFile(autocompletionFile, url); err != nil {
				logrus.Fatal(err)
			}
		}

		switch shellType {
		case "bash":
			fmt.Println(fmt.Sprintf(`
# Run the following commands to install autocompletion
sudo mkdir /etc/bash/completion.d/
sudo cp %s /etc/bash_completion.d/abra
echo "source /etc/bash/completion.d/abra" >> ~/.bashrc
`, autocompletionFile))
		case "zsh":
			fmt.Println(fmt.Sprintf(`
# Run the following commands to install autocompletion
sudo mkdir /etc/zsh/completion.d/
sudo cp %s /etc/zsh/completion.d/abra
echo "PROG=abra\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/completion.d/abra" >> ~/.zshrc
`, autocompletionFile))
		}

		return nil
	},
}