package jpath

import (
	"fmt"
	"math"
	"strconv"
)

type parser struct {
	flow         chan token
	tokensBuffer []token
	path         []PathFn
}

type parserStateFn func(*parser) parserStateFn

// Formats and panics an error message based on a token
func (p *parser) raiseError(tok *token, msg string, args ...interface{}) {
	panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...))
}

func (p *parser) run() {
	for state := parseStart; state != nil; {
		state = state(p)
	}
}

func (p *parser) backup(tok *token) {
	p.tokensBuffer = append(p.tokensBuffer, *tok)
}

func (p *parser) peek() *token {
	if len(p.tokensBuffer) != 0 {
		return &(p.tokensBuffer[0])
	}

	tok, ok := <-p.flow
	if !ok {
		return nil
	}
	p.backup(&tok)
	return &tok
}

func (p *parser) getToken() *token {
	if len(p.tokensBuffer) != 0 {
		tok := p.tokensBuffer[0]
		p.tokensBuffer = p.tokensBuffer[1:]
		return &tok
	}
	tok, ok := <-p.flow
	if !ok {
		return nil
	}
	return &tok
}

func (p *parser) appendPath(fn PathFn) {
	p.path = append(p.path, fn)
}

func parseStart(p *parser) parserStateFn {
	tok := p.getToken()

	if tok == nil || tok.typ == tokenEOF {
		return nil
	}

	if tok.typ != tokenDollar {
		p.raiseError(tok, "Expected '$' at start of expression")
	}

	return parseMatchExpr
}

func parseMatchExpr(p *parser) parserStateFn {
	tok := p.getToken()
	switch tok.typ {
	case tokenDot:
		p.appendPath(matchKeyFn(tok.val))
		return parseMatchExpr
	case tokenDotDot:
		p.appendPath(matchRecurseFn())
		return parseSimpleMatchExpr
	case tokenLBracket:
		return parseBracketExpr
	case tokenStar:
		p.appendPath(matchAnyFn())
		return parseMatchExpr
	case tokenEOF:
		return nil // allow EOF at this stage
	}
	p.raiseError(tok, "expected match expression")
	return nil
}

func parseSimpleMatchExpr(p *parser) parserStateFn {
	tok := p.getToken()
	switch tok.typ {
	case tokenLBracket:
		return parseBracketExpr
	case tokenKey:
		p.appendPath(matchKeyFn(tok.val))
		return parseMatchExpr
	case tokenStar:
		p.appendPath(matchAnyFn())
		return parseMatchExpr
	}
	p.raiseError(tok, "expected match expression")
	return nil
}

func parseBracketExpr(p *parser) parserStateFn {
	tok := p.peek()
	switch tok.typ {
	case tokenInteger:
		// look ahead for a ':'
		p.getToken()
		next := p.peek()
		p.backup(tok)
		if next.typ == tokenColon {
			return parseSliceExpr
		}
		return parseUnionExpr
	case tokenColon:
		return parseSliceExpr
	}
	return parseUnionExpr
}

func parseUnionExpr(p *parser) parserStateFn {
	union := []PathFn{}
	for {
		// parse sub expression
		tok := p.getToken()
		switch tok.typ {
		case tokenInteger:
			idx, _ := strconv.Atoi(tok.val)
			union = append(union, matchIndexFn(idx))
		case tokenKey:
			union = append(union, matchKeyFn(tok.val))
		case tokenQuestion:
			return parseFilterExpr
		case tokenLParen:
			return parseScriptExpr
		default:
			p.raiseError(tok, "expected union sub expression")
		}
		// parse delimiter or terminator
		tok = p.getToken()
		switch tok.typ {
		case tokenComma:
			continue
		case tokenRBracket:
			break
		default:
			p.raiseError(tok, "expected ',' or ']'")
		}
	}
	p.appendPath(matchUnionFn(union))
	return parseMatchExpr
}

func parseSliceExpr(p *parser) parserStateFn {
	// init slice to grab all elements
	start, end, step := 0, math.MaxInt64, 1

	// parse optional start
	tok := p.getToken()
	if tok.typ == tokenInteger {
		start, _ = strconv.Atoi(tok.val)
		tok = p.getToken()
	}
	if tok.typ != tokenColon {
		p.raiseError(tok, "expected ':'")
	}

	// parse optional end
	tok = p.getToken()
	if tok.typ == tokenInteger {
		end, _ = strconv.Atoi(tok.val)
		tok = p.getToken()
	}
	if tok.typ != tokenColon || tok.typ != tokenRBracket {
		p.raiseError(tok, "expected ']' or ':'")
	}

	// parse optional step
	tok = p.getToken()
	if tok.typ == tokenInteger {
		step, _ = strconv.Atoi(tok.val)
		if step < 0 {
			p.raiseError(tok, "step must be a positive value")
		}
		tok = p.getToken()
	}
	if tok.typ != tokenRBracket {
		p.raiseError(tok, "expected ']'")
	}

	p.appendPath(matchSliceFn(start, end, step))
	return parseMatchExpr
}

func parseFilterExpr(p *parser) parserStateFn {
	p.raiseError(p.peek(), "filter expressions are unsupported")
	return nil
}

func parseScriptExpr(p *parser) parserStateFn {
	p.raiseError(p.peek(), "script expressions are unsupported")
	return nil
}

func parse(flow chan token) []PathFn {
	result := []PathFn{}
	parser := &parser{
		flow:         flow,
		tokensBuffer: []token{},
		path:         result,
	}
	parser.run()
	return result
}
