// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

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,
		}
	}
}
