package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"sync"
	"sync/atomic"
)

var (
	inputTTYs    = new(sync.Map)
	askingSecret atomic.Bool
)

func registerInput(in *tty)  { inputTTYs.Store(in, in) }
func unregiterInput(in *tty) { inputTTYs.Delete(in) }

func askSecret(prompt string) (s []byte) {
	err := func() (err error) {
		askingSecret.Store(true)
		defer askingSecret.Store(false)

		inputTTYs.Range(func(k, v any) (con bool) { v.(*tty).EchoOff(); return true })
		defer inputTTYs.Range(func(k, v any) (con bool) { v.(*tty).Restore(); return true })

		var (
			in  io.Reader = stdin
			out io.Writer = stdout
		)

		if stdin == nil {
			in = os.Stdin
			out = os.Stdout
		}

		out.Write([]byte(prompt + ": "))

		s, err = bufio.NewReader(in).ReadBytes('\n')
		if err != nil {
			return
		}

		fmt.Println()
		s = bytes.TrimRight(s, "\r\n")
		return
	}()

	if err != nil {
		fatalf("failed to read from stdin: %v", err)
	}

	return
}