package calc

import (
	"fmt"
	"strings"
	"unicode"
)

type itemType int

const (
	itemError itemType = iota
	itemIdentifier
	itemNum
	itemString
	itemLParen
	itemRParen
	itemComma
	itemEOF
)

const eof byte = 0xff

// item is returned by the lexer.nextItem() as it parses in the input.
type item struct {
	typ itemType
	val string
}

// stateFn is a function that represents the current state of the lexer.
type stateFn func(*lexer) stateFn

// lexer parses an input string and returns items for each lexeme that's found.
type lexer struct {
	input      string    // The string being parsed.
	start      int       // The offset of the current lexical item.
	pos        int       // Current position in input.
	items      chan item // Channel by which items are delivered.
	state      stateFn   // The next lexing function.
	peekBuffer []item    // A peekBuffer for peek'd items.
}

// nextItem returns the next item from the input.
func (l *lexer) nextItem() item {
	if len(l.peekBuffer) > 0 {
		item := l.peekBuffer[0]
		l.peekBuffer = l.peekBuffer[:0]
		return item
	}
	item := <-l.items
	return item
}

// peekItem allows the caller to look ahead and see the next item that
// nextItem() will return.
func (l *lexer) peekItem() item {
	item := <-l.items
	l.peekBuffer = append(l.peekBuffer, item)
	return item
}

// accept consumes the next char if it's from the valid set.
func (l *lexer) accept(valid string) bool {
	if strings.IndexByte(valid, l.next()) >= 0 {
		return true
	}
	l.backUp()
	return false
}

// acceptRun consumes a run of chars from the valid set.
func (l *lexer) acceptRun(valid string) {
	for strings.IndexByte(valid, l.next()) >= 0 {
	}
	l.backUp()
}

// ingore the current text.
func (l *lexer) ignore() {
	l.start = l.pos
}

// errorf returns an error token and terminates the scan by passing
// back a nil pointer that will be the next state, terminating l.run.
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
	l.items <- item{typ: itemError, val: fmt.Sprintf(format, args...)}
	return nil
}

// newLexer returns a new lexer for the given string.
func newLexer(input string) *lexer {
	l := &lexer{
		input:      input,
		start:      0,
		pos:        0,
		items:      make(chan item, 2),
		state:      lexExp,
		peekBuffer: []item{},
	}
	go l.run()
	return l
}

// next returns the next char in the input.
func (l *lexer) next() byte {
	if int(l.pos) >= len(l.input) {
		return eof
	}
	ch := l.input[l.pos]
	l.pos += 1
	return ch
}

// backUp steps back one rune. Can only be called once per call of next.
func (l *lexer) backUp() {
	l.pos -= 1
}

// run runs the state machine for the lexer.
func (l *lexer) run() {
	for l.state = lexExp; l.state != nil; l.state = l.state(l) {
	}
}

// emit puts a new item on the channel.
func (l *lexer) emit(t itemType) {
	l.items <- item{
		typ: t,
		val: l.input[l.start:l.pos],
	}
	l.start = l.pos
}

// lexExp parses the input expression.
func lexExp(l *lexer) stateFn {
	switch r := l.next(); {
	case r == eof:
		l.emit(itemEOF)
		return nil
	case r == '"':
		return lexString
	case unicode.IsLetter(rune(r)):
		return lexIdentifier
	case r == ')':
		l.emit(itemRParen)
		return lexExp
	case r == '(':
		l.emit(itemLParen)
		return lexExp
	case r == ',':
		l.emit(itemComma)
		return lexExp
	case unicode.IsSpace(rune(r)):
		l.ignore()
		return lexExp
	case r == '+' || r == '-' || ('0' <= r && r <= '9'):
		l.backUp()
		return lexNumber
	default:
		return l.errorf("unrecognized char: %#U", r)
	}
}

// lexString parses double-quote delimited strings.
func lexString(l *lexer) stateFn {
	l.ignore()
	r := l.next()
	for ; r != eof; r = l.next() {
		if r == '"' {
			l.backUp()
			l.emit(itemString)
			l.next()
			l.ignore()
			break
		}
	}
	if r == eof {
		l.errorf("Unterminated string: %s", l.input[l.start:l.pos])
	}
	return lexExp
}

// lexNumber parses numbers, things that looks like ints and floats.
func lexNumber(l *lexer) stateFn {
	// Optional leading sign.
	l.accept("+-")
	// Is it hex?
	digits := "0123456789"
	if l.accept("0") && l.accept("xX") {
		digits = "0123456789abcdefABCDEF"
	}
	l.acceptRun(digits)
	if l.accept(".") {
		l.acceptRun(digits)
	}
	if l.accept("eE") {
		l.accept("+-")
		l.acceptRun("0123456789")
	}
	l.emit(itemNum)
	return lexExp
}

// lexIdentifier parses function names.
func lexIdentifier(l *lexer) stateFn {
	for {
		r := l.next()
		if !unicode.IsLetter(rune(r)) && !unicode.IsDigit(rune(r)) && r != '_' {
			l.backUp()
			break
		}
	}
	l.emit(itemIdentifier)
	return lexExp
}
