package ssh

import (
	
	
	
	
)

// ErrUnsupported is returned when the platform does not support PTY.
var ErrUnsupported = errors.New("pty unsupported")

// NewPtyWriter creates a writer that handles when the session has a active
// PTY, replacing the \n with \r\n.
func ( io.Writer) io.Writer {
	return ptyWriter{
		w: ,
	}
}

var _ io.Writer = ptyWriter{}

type ptyWriter struct {
	w io.Writer
}

func ( ptyWriter) ( []byte) (int, error) {
	 := len()
	// normalize \n to \r\n when pty is accepted.
	// this is a hardcoded shortcut since we don't support terminal modes.
	 = bytes.ReplaceAll(, []byte{'\n'}, []byte{'\r', '\n'})
	 = bytes.ReplaceAll(, []byte{'\r', '\r', '\n'}, []byte{'\r', '\n'})
	,  := .w.Write()
	if  >  {
		 = 
	}
	return , 
}

// NewPtyReadWriter return an io.ReadWriter that delegates the read to the
// given io.ReadWriter, and the writes to a ptyWriter.
func ( io.ReadWriter) io.ReadWriter {
	return readWriterDelegate{
		w: NewPtyWriter(),
		r: ,
	}
}

var _ io.ReadWriter = readWriterDelegate{}

type readWriterDelegate struct {
	w io.Writer
	r io.Reader
}

func ( readWriterDelegate) ( []byte) ( int,  error) {
	return .r.Read()
}

func ( readWriterDelegate) ( []byte) ( int,  error) {
	return .w.Write()
}

// PtyStartOption configures how Pty.Start runs a command.
type PtyStartOption func(*ptyStartConfig)

type ptyStartConfig struct {
	jobControl bool
}

// WithJobControl enables job control when starting the command: on Unix,
// the command is put in its own session with the PTY slave as its
// controlling terminal, so interactive shells get working signal handling
// (e.g. ^C, ^Z).
//
// Leave it disabled (the default) when running multiple commands
// sequentially against the same PTY, or when managing the command's process
// attributes yourself via exec.Cmd.SysProcAttr.
func () PtyStartOption {
	return func( *ptyStartConfig) {
		.jobControl = true
	}
}

// Start starts a *exec.Cmd attached to the Session. If a PTY is allocated,
// it will use that for I/O.
// On Windows, the process execution lifecycle is not managed by Go and has to
// be managed manually. This means that c.Wait() won't work.
// See https://github.com/charmbracelet/x/blob/main/exp/term/conpty/conpty_windows.go
func ( *Pty) ( *exec.Cmd,  ...PtyStartOption) error {
	 := ptyStartConfig{}
	for ,  := range  {
		(&)
	}
	return .start(, )
}