// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package terminal

import (
	"os"
	"io"
)

// Shell contains the state for running a VT100 terminal that is capable of
// reading lines of input.
type Shell struct {
	c      io.ReadWriter
	prompt string

	// line is the current line being entered.
	line []byte
	// pos is the logical position of the cursor in line
	pos int

	// cursorX contains the current X value of the cursor where the left
	// edge is 0. cursorY contains the row number where the first row of
	// the current line is 0.
	cursorX, cursorY int
	// maxLine is the greatest value of cursorY so far.
	maxLine int

	termWidth, termHeight int

	// outBuf contains the terminal data to be sent.
	outBuf []byte
	// remainder contains the remainder of any partial key sequences after
	// a read. It aliases into inBuf.
	remainder []byte
	inBuf     [256]byte
}

// NewShell runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
// a local terminal, that terminal must first have been put into raw mode.
// prompt is a string that is written at the start of each input line (i.e.
// "> ").
func NewShell(c io.ReadWriter, prompt string) *Shell {
	return &Shell{
		c:          c,
		prompt:     prompt,
		termWidth:  80,
		termHeight: 24,
	}
}

const (
	keyCtrlD     = 4
	keyEnter     = '\r'
	keyEscape    = 27
	keyBackspace = 127
	keyUnknown   = 256 + iota
	keyUp
	keyDown
	keyLeft
	keyRight
	keyAltLeft
	keyAltRight
)

// bytesToKey tries to parse a key sequence from b. If successful, it returns
// the key and the remainder of the input. Otherwise it returns -1.
func bytesToKey(b []byte) (int, []byte) {
	if len(b) == 0 {
		return -1, nil
	}

	if b[0] != keyEscape {
		return int(b[0]), b[1:]
	}

	if len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
		switch b[2] {
		case 'A':
			return keyUp, b[3:]
		case 'B':
			return keyDown, b[3:]
		case 'C':
			return keyRight, b[3:]
		case 'D':
			return keyLeft, b[3:]
		}
	}

	if len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
		switch b[5] {
		case 'C':
			return keyAltRight, b[6:]
		case 'D':
			return keyAltLeft, b[6:]
		}
	}

	// If we get here then we have a key that we don't recognise, or a
	// partial sequence. It's not clear how one should find the end of a
	// sequence without knowing them all, but it seems that [a-zA-Z] only
	// appears at the end of a sequence.
	for i, c := range b[0:] {
		if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' {
			return keyUnknown, b[i+1:]
		}
	}

	return -1, b
}

// queue appends data to the end of ss.outBuf
func (ss *Shell) queue(data []byte) {
	if len(ss.outBuf)+len(data) > cap(ss.outBuf) {
		newOutBuf := make([]byte, len(ss.outBuf), 2*(len(ss.outBuf)+len(data)))
		copy(newOutBuf, ss.outBuf)
		ss.outBuf = newOutBuf
	}

	oldLen := len(ss.outBuf)
	ss.outBuf = ss.outBuf[:len(ss.outBuf)+len(data)]
	copy(ss.outBuf[oldLen:], data)
}

var eraseUnderCursor = []byte{' ', keyEscape, '[', 'D'}

func isPrintable(key int) bool {
	return key >= 32 && key < 127
}

// moveCursorToPos appends data to ss.outBuf which will move the cursor to the
// given, logical position in the text.
func (ss *Shell) moveCursorToPos(pos int) {
	x := len(ss.prompt) + pos
	y := x / ss.termWidth
	x = x % ss.termWidth

	up := 0
	if y < ss.cursorY {
		up = ss.cursorY - y
	}

	down := 0
	if y > ss.cursorY {
		down = y - ss.cursorY
	}

	left := 0
	if x < ss.cursorX {
		left = ss.cursorX - x
	}

	right := 0
	if x > ss.cursorX {
		right = x - ss.cursorX
	}

	movement := make([]byte, 3*(up+down+left+right))
	m := movement
	for i := 0; i < up; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'A'
		m = m[3:]
	}
	for i := 0; i < down; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'B'
		m = m[3:]
	}
	for i := 0; i < left; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'D'
		m = m[3:]
	}
	for i := 0; i < right; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'C'
		m = m[3:]
	}

	ss.cursorX = x
	ss.cursorY = y
	ss.queue(movement)
}

const maxLineLength = 4096

// handleKey processes the given key and, optionally, returns a line of text
// that the user has entered.
func (ss *Shell) handleKey(key int) (line string, ok bool) {
	switch key {
	case keyBackspace:
		if ss.pos == 0 {
			return
		}
		ss.pos--

		copy(ss.line[ss.pos:], ss.line[1+ss.pos:])
		ss.line = ss.line[:len(ss.line)-1]
		ss.writeLine(ss.line[ss.pos:])
		ss.moveCursorToPos(ss.pos)
		ss.queue(eraseUnderCursor)
	case keyAltLeft:
		// move left by a word.
		if ss.pos == 0 {
			return
		}
		ss.pos--
		for ss.pos > 0 {
			if ss.line[ss.pos] != ' ' {
				break
			}
			ss.pos--
		}
		for ss.pos > 0 {
			if ss.line[ss.pos] == ' ' {
				ss.pos++
				break
			}
			ss.pos--
		}
		ss.moveCursorToPos(ss.pos)
	case keyAltRight:
		// move right by a word.
		for ss.pos < len(ss.line) {
			if ss.line[ss.pos] == ' ' {
				break
			}
			ss.pos++
		}
		for ss.pos < len(ss.line) {
			if ss.line[ss.pos] != ' ' {
				break
			}
			ss.pos++
		}
		ss.moveCursorToPos(ss.pos)
	case keyLeft:
		if ss.pos == 0 {
			return
		}
		ss.pos--
		ss.moveCursorToPos(ss.pos)
	case keyRight:
		if ss.pos == len(ss.line) {
			return
		}
		ss.pos++
		ss.moveCursorToPos(ss.pos)
	case keyEnter:
		ss.moveCursorToPos(len(ss.line))
		ss.queue([]byte("\r\n"))
		line = string(ss.line)
		ok = true
		ss.line = ss.line[:0]
		ss.pos = 0
		ss.cursorX = 0
		ss.cursorY = 0
		ss.maxLine = 0
	default:
		if !isPrintable(key) {
			return
		}
		if len(ss.line) == maxLineLength {
			return
		}
		if len(ss.line) == cap(ss.line) {
			newLine := make([]byte, len(ss.line), 2*(1+len(ss.line)))
			copy(newLine, ss.line)
			ss.line = newLine
		}
		ss.line = ss.line[:len(ss.line)+1]
		copy(ss.line[ss.pos+1:], ss.line[ss.pos:])
		ss.line[ss.pos] = byte(key)
		ss.writeLine(ss.line[ss.pos:])
		ss.pos++
		ss.moveCursorToPos(ss.pos)
	}
	return
}

func (ss *Shell) writeLine(line []byte) {
	for len(line) != 0 {
		if ss.cursorX == ss.termWidth {
			ss.queue([]byte("\r\n"))
			ss.cursorX = 0
			ss.cursorY++
			if ss.cursorY > ss.maxLine {
				ss.maxLine = ss.cursorY
			}
		}

		remainingOnLine := ss.termWidth - ss.cursorX
		todo := len(line)
		if todo > remainingOnLine {
			todo = remainingOnLine
		}
		ss.queue(line[:todo])
		ss.cursorX += todo
		line = line[todo:]
	}
}

func (ss *Shell) Write(buf []byte) (n int, err os.Error) {
	return ss.c.Write(buf)
}

// ReadLine returns a line of input from the terminal.
func (ss *Shell) ReadLine() (line string, err os.Error) {
	ss.writeLine([]byte(ss.prompt))
	ss.c.Write(ss.outBuf)
	ss.outBuf = ss.outBuf[:0]

	for {
		// ss.remainder is a slice at the beginning of ss.inBuf
		// containing a partial key sequence
		readBuf := ss.inBuf[len(ss.remainder):]
		var n int
		n, err = ss.c.Read(readBuf)
		if err != nil {
			return
		}

		if err == nil {
			ss.remainder = ss.inBuf[:n+len(ss.remainder)]
			rest := ss.remainder
			lineOk := false
			for !lineOk {
				var key int
				key, rest = bytesToKey(rest)
				if key < 0 {
					break
				}
				if key == keyCtrlD {
					return "", os.EOF
				}
				line, lineOk = ss.handleKey(key)
			}
			if len(rest) > 0 {
				n := copy(ss.inBuf[:], rest)
				ss.remainder = ss.inBuf[:n]
			} else {
				ss.remainder = nil
			}
			ss.c.Write(ss.outBuf)
			ss.outBuf = ss.outBuf[:0]
			if lineOk {
				return
			}
			continue
		}
	}
	panic("unreachable")
}
