package runtime

import (
	"os"
	"os/exec"

	"github.com/creack/pty"
)

// CreatePTY starts cmd attached to a PTY and returns the PTY file.
func CreatePTY(cmd *exec.Cmd) (*os.File, error) {
	ptmx, err := pty.Start(cmd)
	if err != nil {
		return nil, err
	}
	return ptmx, nil
}

// ReadLoop reads from a PTY in non-blocking mode and streams chunks to onData.
func ReadLoop(ptyFile *os.File, stop <-chan struct{}, onData func([]byte) error) error {
	buf := make([]byte, 4096)
	for {
		n, err := ptyFile.Read(buf)
		if n > 0 {
			if writeErr := onData(buf[:n]); writeErr != nil {
				return writeErr
			}
		}
		if err != nil {
			return err
		}

		select {
		case <-stop:
			return nil
		default:
		}
	}
}

// Write sends data to the PTY.
func Write(ptyFile *os.File, data []byte) error {
	_, err := ptyFile.Write(data)
	return err
}
