package command

import (
	"bufio"
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"os/signal"
	"strings"
	"sync"
	"sync/atomic"
	"unicode"

	"github.com/bgentry/speakeasy"
	"github.com/hashicorp/terraform/internal/terraform"
	"github.com/mattn/go-isatty"
	"github.com/mitchellh/colorstring"
)

var defaultInputReader io.Reader
var defaultInputWriter io.Writer
var testInputResponse []string
var testInputResponseMap map[string]string

// UIInput is an implementation of terraform.UIInput that asks the CLI
// for input stdin.
type UIInput struct {
	// Colorize will color the output.
	Colorize *colorstring.Colorize

	// Reader and Writer for IO. If these aren't set, they will default to
	// Stdin and Stdout respectively.
	Reader io.Reader
	Writer io.Writer

	listening int32
	result    chan string
	err       chan string

	interrupted bool
	l           sync.Mutex
	once        sync.Once
}

func (i *UIInput) Input(ctx context.Context, opts *terraform.InputOpts) (string, error) {
	i.once.Do(i.init)

	r := i.Reader
	w := i.Writer
	if r == nil {
		r = defaultInputReader
	}
	if w == nil {
		w = defaultInputWriter
	}
	if r == nil {
		r = os.Stdin
	}
	if w == nil {
		w = os.Stdout
	}

	// Make sure we only ask for input once at a time. Terraform
	// should enforce this, but it doesn't hurt to verify.
	i.l.Lock()
	defer i.l.Unlock()

	// If we're interrupted, then don't ask for input
	if i.interrupted {
		return "", errors.New("interrupted")
	}

	// If we have test results, return those. testInputResponse is the
	// "old" way of doing it and we should remove that.
	if testInputResponse != nil {
		v := testInputResponse[0]
		testInputResponse = testInputResponse[1:]
		return v, nil
	}

	// testInputResponseMap is the new way for test responses, based on
	// the query ID.
	if testInputResponseMap != nil {
		v, ok := testInputResponseMap[opts.Id]
		if !ok {
			return "", fmt.Errorf("unexpected input request in test: %s", opts.Id)
		}

		delete(testInputResponseMap, opts.Id)
		return v, nil
	}

	log.Printf("[DEBUG] command: asking for input: %q", opts.Query)

	// Listen for interrupts so we can cancel the input ask
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, os.Interrupt)
	defer signal.Stop(sigCh)

	// Build the output format for asking
	var buf bytes.Buffer
	buf.WriteString("[reset]")
	buf.WriteString(fmt.Sprintf("[bold]%s[reset]\n", opts.Query))
	if opts.Description != "" {
		s := bufio.NewScanner(strings.NewReader(opts.Description))
		for s.Scan() {
			buf.WriteString(fmt.Sprintf("  %s\n", s.Text()))
		}
		buf.WriteString("\n")
	}
	if opts.Default != "" {
		buf.WriteString("  [bold]Default:[reset] ")
		buf.WriteString(opts.Default)
		buf.WriteString("\n")
	}
	buf.WriteString("  [bold]Enter a value:[reset] ")

	// Ask the user for their input
	if _, err := fmt.Fprint(w, i.Colorize.Color(buf.String())); err != nil {
		return "", err
	}

	// Listen for the input in a goroutine. This will allow us to
	// interrupt this if we are interrupted (SIGINT).
	go func() {
		if !atomic.CompareAndSwapInt32(&i.listening, 0, 1) {
			return // We are already listening for input.
		}
		defer atomic.CompareAndSwapInt32(&i.listening, 1, 0)

		var line string
		var err error
		if opts.Secret && isatty.IsTerminal(os.Stdin.Fd()) {
			line, err = speakeasy.Ask("")
		} else {
			buf := bufio.NewReader(r)
			line, err = buf.ReadString('\n')
		}
		if err != nil {
			log.Printf("[ERR] UIInput scan err: %s", err)
			i.err <- string(err.Error())
		} else {
			i.result <- strings.TrimRightFunc(line, unicode.IsSpace)
		}
	}()

	select {
	case err := <-i.err:
		return "", errors.New(err)

	case line := <-i.result:
		fmt.Fprint(w, "\n")

		if line == "" {
			line = opts.Default
		}

		return line, nil
	case <-ctx.Done():
		// Print a newline so that any further output starts properly
		// on a new line.
		fmt.Fprintln(w)

		return "", ctx.Err()
	case <-sigCh:
		// Print a newline so that any further output starts properly
		// on a new line.
		fmt.Fprintln(w)

		// Mark that we were interrupted so future Ask calls fail.
		i.interrupted = true

		return "", errors.New("interrupted")
	}
}

func (i *UIInput) init() {
	i.result = make(chan string)
	i.err = make(chan string)

	if i.Colorize == nil {
		i.Colorize = &colorstring.Colorize{
			Colors:  colorstring.DefaultColors,
			Disable: true,
		}
	}
}
