package autocomplete

import (
	"fmt"
	"sort"

	"coopcloud.tech/abra/pkg/app"
	appPkg "coopcloud.tech/abra/pkg/app"
	"coopcloud.tech/abra/pkg/recipe"
	"github.com/spf13/cobra"
)

// AppNameComplete copletes app names.
func AppNameComplete() ([]string, cobra.ShellCompDirective) {
	appFiles, err := app.LoadAppFiles("")
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	var appNames []string
	for appName := range appFiles {
		appNames = append(appNames, appName)
	}

	return appNames, cobra.ShellCompDirectiveDefault
}

func ServiceNameComplete(appName string) ([]string, cobra.ShellCompDirective) {
	serviceNames, err := app.GetAppServiceNames(appName)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	return serviceNames, cobra.ShellCompDirectiveDefault
}

// RecipeNameComplete completes recipe names.
func RecipeNameComplete() ([]string, cobra.ShellCompDirective) {
	catl, err := recipe.ReadRecipeCatalogue(false)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	var recipeNames []string
	for name := range catl {
		recipeNames = append(recipeNames, name)
	}

	return recipeNames, cobra.ShellCompDirectiveDefault
}

// RecipeVersionComplete completes versions for the recipe.
func RecipeVersionComplete(recipeName string) ([]string, cobra.ShellCompDirective) {
	catl, err := recipe.ReadRecipeCatalogue(true)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	var recipeVersions []string
	for _, v := range catl[recipeName].Versions {
		for v2 := range v {
			recipeVersions = append(recipeVersions, v2)
		}
	}

	return recipeVersions, cobra.ShellCompDirectiveDefault
}

// ServerNameComplete completes server names.
func ServerNameComplete() ([]string, cobra.ShellCompDirective) {
	files, err := app.LoadAppFiles("")
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	var serverNames []string
	for _, appFile := range files {
		serverNames = append(serverNames, appFile.Server)
	}

	return serverNames, cobra.ShellCompDirectiveDefault
}

// CommandNameComplete completes recipe commands.
func CommandNameComplete(appName string) ([]string, cobra.ShellCompDirective) {
	app, err := app.Get(appName)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	cmdNames, err := appPkg.ReadAbraShCmdNames(app.Recipe.AbraShPath)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	sort.Strings(cmdNames)

	return cmdNames, cobra.ShellCompDirectiveDefault
}

// SecretsComplete completes recipe secrets.
func SecretComplete(recipeName string) ([]string, cobra.ShellCompDirective) {
	r := recipe.Get(recipeName)

	config, err := r.GetComposeConfig(nil)
	if err != nil {
		err := fmt.Sprintf("autocomplete failed: %s", err)
		return []string{err}, cobra.ShellCompDirectiveError
	}

	var secretNames []string
	for name := range config.Secrets {
		secretNames = append(secretNames, name)
	}

	return secretNames, cobra.ShellCompDirectiveDefault
}
