package bash

import (
	
	
	

	
)

var sanitizer = strings.NewReplacer(
	"\n", ``,
	"\r", ``,
	"\t", ``,
)

var valueReplacer = strings.NewReplacer(
	`\`, `\\`,
	`"`, `\"`,
	`$`, `\$`,
	"`", "\\`",
)

var displayReplacer = strings.NewReplacer(
	`${`, `\\\${`,
)

func commonPrefix(,  string) string {
	 := 0
	for  < len() &&  < len() && [] == [] {
		++
	}
	return [0:]
}

func commonDisplayPrefix( ...common.RawValue) ( string) {
	for ,  := range  {
		if  == 0 {
			 = .Display
		} else {
			 = commonPrefix(, .Display)
		}
	}
	return
}

func commonValuePrefix( ...common.RawValue) ( string) {
	for ,  := range  {
		if  == 0 {
			 = .Value
		} else {
			 = commonPrefix(, .Value)
		}
	}
	return
}

// ActionRawValues formats values for bash.
func ( string,  common.Meta,  common.RawValues) string {
	for ,  := range  {
		[].Value = strings.TrimPrefix(.Value, wordbreakPrefix)
	}

	 := strings.TrimPrefix(, wordbreakPrefix) // last segment of currentWord split by COMP_WORDBREAKS
	if len() > 1 && commonDisplayPrefix(...) != "" {
		// When all display values have the same prefix bash will insert is as partial completion (which skips prefixes/formatting).
		if  := commonValuePrefix(...);  !=  {
			// replace values with common value prefix
			 = common.RawValuesFrom(commonValuePrefix(...))
		} else {
			// prevent insertion of partial display values by prefixing one with space
			[0].Display = " " + [0].Display
		}
		.Nospace.Add('*')
	}

	 := true
	 := make([]string, len())
	for ,  := range  {
		if len() == 1 {
			if !.Nospace.Matches(.Value) {
				 = false
			}

			[] = sanitizer.Replace(.Value)
			if requiresQuoting([]) {
				[] = valueReplacer.Replace([])
				switch {
				case strings.HasPrefix([], "~"): // assume homedir expansion
					if  := strings.SplitAfterN([], "/", 2); len() == 2 {
						[] = fmt.Sprintf(`%v"%v"`, [0], [1])
					} else {
						// TODO homedir expansion won't work this way, but shouldn't reach this point anyway.
						[] = fmt.Sprintf(`~"%v"`, strings.TrimPrefix([], "~"))
					}
				default:
					[] = fmt.Sprintf(`"%v"`, [])
				}
			}
		} else {
			.Display = displayReplacer.Replace(.Display)
			.Description = displayReplacer.Replace(.Description)
			if .Description != "" {
				[] = fmt.Sprintf("%v (%v)", .Display, sanitizer.Replace(.TrimmedDescription()))
			} else {
				[] = .Display
			}
		}
	}
	return fmt.Sprintf("%v\001%v", , strings.Join(, "\n"))
}

func requiresQuoting( string) bool {
	 := " \t\r\n`" + `[]{}()<>;|$&:*#`
	 += os.Getenv("COMP_WORDBREAKS")
	 += `\`
	return strings.ContainsAny(, )

}