package input

import (
	"io"
	"os"
	"os/exec"
	"runtime"
)

type Keyboard struct {
}

func NewKeyboard() Keyboard {
	switch runtime.GOOS {
	case "linux":
		if err := exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run(); err != nil {
			panic(err)
		} else if err := exec.Command("stty", "-F", "/dev/tty", "-echo").Run(); err != nil {
			panic(err)
		}
	case "darwin":
		if err := exec.Command("stty", "-f", "/dev/tty", "cbreak", "min", "1").Run(); err != nil {
			panic(err)
		} else if err := exec.Command("stty", "-f", "/dev/tty", "-echo").Run(); err != nil {
			panic(err)
		}
	default:
		panic(runtime.GOOS)
	}
	return Keyboard{}
}

func (kb Keyboard) Close() {
	switch runtime.GOOS {
	case "linux":
		if err := exec.Command("stty", "-F", "/dev/tty", "echo").Run(); err != nil {
			panic(err)
		}
	case "darwin":
		if err := exec.Command("stty", "-f", "/dev/tty", "echo").Run(); err != nil {
			panic(err)
		}
	}
}

func (kb Keyboard) Read() []Button {
	b := make([]byte, 5)
	n, err := os.Stdin.Read(b)
	if err != nil && err != io.EOF {
		panic(err)
	}

	result := make([]Button, 0, n)
	for i := 0; i < n; i++ {
		if b[i] != '\n' {
			result = append(result, Button{Char: b[i], Down: true})
		}
	}
	return result
}
