1package commands
2
3import (
4	"bufio"
5	"fmt"
6	"io"
7	"os"
8	"strings"
9)
10
11// retrieveUserInput is a function that can retrieve user input in form of string. By default,
12// it will prompt the user. In test, you can replace this with code that returns the appropriate response.
13var retrieveUserInput = func(message string) (string, error) {
14	return readUserInput(os.Stdin, message)
15}
16
17// readUserInput is similar to retrieveUserInput but takes an explicit
18// io.Reader to read user input from. It is meant to allow simplified testing
19// as to-be-read inputs can be injected conveniently.
20func readUserInput(in io.Reader, message string) (string, error) {
21	reader := bufio.NewReader(in)
22	warnConfirm("Are you sure you want to " + message + " (y/N) ? ")
23	answer, err := reader.ReadString('\n')
24	if err != nil {
25		return "", err
26	}
27
28	answer = strings.TrimRight(answer, "\r\n")
29
30	return strings.ToLower(answer), nil
31}
32
33// AskForConfirm parses and verifies user input for confirmation.
34func AskForConfirm(message string) error {
35	answer, err := retrieveUserInput(message)
36	if err != nil {
37		return fmt.Errorf("Unable to parse users input: %s", err)
38	}
39
40	if answer != "y" && answer != "ye" && answer != "yes" {
41		return fmt.Errorf("Invalid user input")
42	}
43
44	return nil
45}
46
47// AskForConfirmDelete builds a message to ask the user to confirm deleting
48// one or multiple resources and then sends it through to AskForConfirm to
49// parses and verifies user input.
50func AskForConfirmDelete(resourceType string, count int) error {
51	message := fmt.Sprintf("delete this %s?", resourceType)
52	if count > 1 {
53		resourceType = resourceType + "s"
54		message = fmt.Sprintf("delete %d %s?", count, resourceType)
55	}
56
57	err := AskForConfirm(message)
58	if err != nil {
59		return err
60	}
61
62	return nil
63}
64