package carapace

import (
	
	

	
	
)

func registerValidArgsFunction( *cobra.Command) {
	if .ValidArgsFunction == nil {
		.ValidArgsFunction = func( *cobra.Command,  []string,  string) ([]string, cobra.ShellCompDirective) {
			 := Action{}.Invoke(Context{Args: , Value: }) // TODO just IvokedAction{} ok?
			if storage.hasPositional(, len()) {
				 = storage.getPositional(, len()).Invoke(Context{Args: , Value: })
			}
			return cobraValuesFor(), cobraDirectiveFor()
		}
	}
}

func registerFlagCompletion( *cobra.Command) {
	.LocalFlags().VisitAll(func( *pflag.Flag) {
		if !storage.hasFlag(, .Name) {
			return // skip if not defined in carapace
		}
		if ,  := .GetFlagCompletionFunc(.Name);  {
			return // skip if already defined in cobra
		}

		 := .RegisterFlagCompletionFunc(.Name, func( *cobra.Command,  []string,  string) ([]string, cobra.ShellCompDirective) {
			 := storage.getFlag(, .Name)
			 := .Invoke(Context{Args: , Value: }) // TODO cmd might differ for persistentflags and either way args or cmd will be wrong
			return cobraValuesFor(), cobraDirectiveFor()
		})
		if  != nil {
			LOG.Printf("failed to register flag completion func: %v", .Error())
		}
	})
}

func cobraValuesFor( InvokedAction) []string {
	 := make([]string, len(.action.rawValues))
	for ,  := range .action.rawValues {
		if .Description != "" {
			[] = fmt.Sprintf("%v\t%v", .Value, .Description)
		} else {
			[] = .Value
		}
	}
	return 
}

func cobraDirectiveFor( InvokedAction) cobra.ShellCompDirective {
	 := cobra.ShellCompDirectiveNoFileComp
	for ,  := range .action.rawValues {
		if .action.meta.Nospace.Matches(.Value) {
			 =  | cobra.ShellCompDirectiveNoSpace
			break
		}
	}
	return 
}

type compDirective cobra.ShellCompDirective

func ( compDirective) ( cobra.ShellCompDirective) bool {
	return &compDirective() != 0
}

func ( compDirective) ( ...string) Action {
	var  Action
	switch {
	case .matches(cobra.ShellCompDirectiveError):
		return ActionMessage("an error occurred")
	case .matches(cobra.ShellCompDirectiveFilterDirs):
		switch len() {
		case 0:
			 = ActionDirectories()
		default:
			 = ActionDirectories().Chdir([0])
		}
	case .matches(cobra.ShellCompDirectiveFilterFileExt):
		 := make([]string, 0)
		for ,  := range  {
			 = append(, "."+)
		}
		return ActionFiles(...)
	case len() == 0 && !.matches(cobra.ShellCompDirectiveNoFileComp):
		 = ActionFiles()
	default:
		 := make([]string, 0)
		for ,  := range  {
			if  := strings.SplitN(, "\t", 2); len() == 2 {
				 = append(, [0], [1])
			} else {
				 = append(, [0], "")
			}
		}
		 = ActionValuesDescribed(...)
	}

	if .matches(cobra.ShellCompDirectiveNoSpace) {
		 = .NoSpace()
	}

	return 
}