package wizard import ( "bufio" "crypto/rand" "encoding/hex" "fmt" "os" "strconv" "strings" ) // PromptString prompts for a string value with a default func PromptString(prompt string, defaultValue string) string { if defaultValue != "" { fmt.Printf("%s [%s]: ", prompt, defaultValue) } else { fmt.Printf("%s: ", prompt) } reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') input = strings.TrimSpace(input) if input == "" { return defaultValue } return input } // PromptPassword prompts for a password (hidden input would be nice, but we'll use simple input for now) func PromptPassword(prompt string) string { fmt.Printf("%s: ", prompt) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') return strings.TrimSpace(input) } // PromptBool prompts for a yes/no answer func PromptBool(prompt string, defaultValue bool) bool { defaultStr := "y/N" if defaultValue { defaultStr = "Y/n" } fmt.Printf("%s [%s]: ", prompt, defaultStr) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') input = strings.TrimSpace(strings.ToLower(input)) if input == "" { return defaultValue } return input == "y" || input == "yes" } // PromptChoice prompts for a choice from a list func PromptChoice(prompt string, choices []string, defaultIndex int) int { fmt.Println(prompt) for i, choice := range choices { marker := " " if i == defaultIndex { marker = "●" } else { marker = "○" } fmt.Printf(" %s %d. %s\n", marker, i+1, choice) } fmt.Println() fmt.Printf("Choice [%d]: ", defaultIndex+1) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') input = strings.TrimSpace(input) if input == "" { return defaultIndex } choice, err := strconv.Atoi(input) if err != nil || choice < 1 || choice > len(choices) { fmt.Println("Invalid choice, using default") return defaultIndex } return choice - 1 } // GenerateRandomSecret generates a random hex string for JWT secrets func GenerateRandomSecret(bytes int) (string, error) { b := make([]byte, bytes) if _, err := rand.Read(b); err != nil { return "", err } return hex.EncodeToString(b), nil } // PromptOrGenerate prompts for a value or generates one func PromptOrGenerate(prompt string, generator func() (string, error)) string { fmt.Printf("%s (press Enter to generate): ", prompt) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') input = strings.TrimSpace(input) if input == "" { generated, err := generator() if err != nil { fmt.Printf("Error generating: %v\n", err) return "" } fmt.Printf("Generated: %s\n", generated) return generated } return input } // PrintHeader prints a formatted section header func PrintHeader(title string) { fmt.Println() fmt.Println(title) fmt.Println(strings.Repeat("-", len(title))) } // PrintSuccess prints a success message func PrintSuccess(message string) { fmt.Printf("✓ %s\n", message) } // PrintError prints an error message func PrintError(message string) { fmt.Fprintf(os.Stderr, "✗ %s\n", message) } // PrintInfo prints an informational message func PrintInfo(message string) { fmt.Printf("ℹ %s\n", message) } // Confirm asks for confirmation before proceeding func Confirm(prompt string) bool { return PromptBool(prompt, false) }