package server

import (
	"fmt"
	"strings"

	"coopcloud.tech/abra/cli/internal"
	"coopcloud.tech/abra/pkg/config"
	contextPkg "coopcloud.tech/abra/pkg/context"
	"coopcloud.tech/abra/pkg/formatter"
	"coopcloud.tech/abra/pkg/i18n"
	"coopcloud.tech/abra/pkg/log"
	"github.com/docker/cli/cli/connhelper/ssh"
	"github.com/spf13/cobra"
)

// translators: `abra server list` aliases. use a comma separated list of
// aliases with no spaces in between
var serverListAliases = i18n.G("ls")

var ServerListCommand = &cobra.Command{
	// translators: `server list` command
	Use:     i18n.G("list [flags]"),
	Aliases: strings.Split(serverListAliases, ","),
	// translators: Short description for `server list` command
	Short: i18n.G("List managed servers"),
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		dockerContextStore := contextPkg.NewDefaultDockerContextStore()
		contexts, err := dockerContextStore.Store.List()
		if err != nil {
			log.Fatal(err)
		}

		table, err := formatter.CreateTable()
		if err != nil {
			log.Fatal(err)
		}

		headers := []string{i18n.G("NAME"), i18n.G("HOST")}
		table.Headers(headers...)

		serverNames, err := config.ReadServerNames()
		if err != nil {
			log.Fatal(err)
		}

		var rows [][]string
		for _, serverName := range serverNames {
			var row []string
			for _, dockerCtx := range contexts {
				endpoint, err := contextPkg.GetContextEndpoint(dockerCtx)
				if err != nil && strings.Contains(err.Error(), "does not exist") {
					// No local context found, we can continue safely
					continue
				}

				if dockerCtx.Name == serverName {
					sp, err := ssh.ParseURL(endpoint)
					if err != nil {
						log.Fatal(err)
					}

					if sp.Host == "" {
						sp.Host = i18n.G("unknown")
					}

					row = []string{serverName, sp.Host}
					rows = append(rows, row)
				}
			}

			if len(row) == 0 {
				if serverName == "default" {
					row = []string{serverName, i18n.G("local")}
				} else {
					row = []string{serverName, i18n.G("unknown")}
				}
				rows = append(rows, row)
			}

			table.Row(row...)
		}

		if internal.MachineReadable {
			out, err := formatter.ToJSON(headers, rows)
			if err != nil {
				log.Fatal(i18n.G("unable to render to JSON: %s", err))
			}

			fmt.Println(out)

			return
		}

		if err := formatter.PrintTable(table); err != nil {
			log.Fatal(err)
		}
	},
}

func init() {
	ServerListCommand.Flags().BoolVarP(
		&internal.MachineReadable,
		i18n.G("machine"),
		i18n.G("m"),
		false,
		i18n.G("print machine-readable output"),
	)
}
