package dbus

import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)

// Heavily inspired by the lexer from text/template.

type varToken struct {
	typ varTokenType
	val string
}

type varTokenType byte

const (
	tokEOF varTokenType = iota
	tokError
	tokNumber
	tokString
	tokBool
	tokArrayStart
	tokArrayEnd
	tokDictStart
	tokDictEnd
	tokVariantStart
	tokVariantEnd
	tokComma
	tokColon
	tokType
	tokByteString
)

type varLexer struct {
	input  string
	start  int
	pos    int
	width  int
	tokens []varToken
}

type lexState func(*varLexer) lexState

func varLex(s string) []varToken {
	l := &varLexer{input: s}
	l.run()
	return l.tokens
}

func (l *varLexer) accept(valid string) bool {
	if strings.IndexRune(valid, l.next()) >= 0 {
		return true
	}
	l.backup()
	return false
}

func (l *varLexer) backup() {
	l.pos -= l.width
}

func (l *varLexer) emit(t varTokenType) {
	l.tokens = append(l.tokens, varToken{t, l.input[l.start:l.pos]})
	l.start = l.pos
}

func (l *varLexer) errorf(format string, v ...interface{}) lexState {
	l.tokens = append(l.tokens, varToken{
		tokError,
		fmt.Sprintf(format, v...),
	})
	return nil
}

func (l *varLexer) ignore() {
	l.start = l.pos
}

func (l *varLexer) next() rune {
	var r rune

	if l.pos >= len(l.input) {
		l.width = 0
		return -1
	}
	r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
	l.pos += l.width
	return r
}

func (l *varLexer) run() {
	for state := varLexNormal; state != nil; {
		state = state(l)
	}
}

func (l *varLexer) peek() rune {
	r := l.next()
	l.backup()
	return r
}

func varLexNormal(l *varLexer) lexState {
	for {
		r := l.next()
		switch {
		case r == -1:
			l.emit(tokEOF)
			return nil
		case r == '[':
			l.emit(tokArrayStart)
		case r == ']':
			l.emit(tokArrayEnd)
		case r == '{':
			l.emit(tokDictStart)
		case r == '}':
			l.emit(tokDictEnd)
		case r == '<':
			l.emit(tokVariantStart)
		case r == '>':
			l.emit(tokVariantEnd)
		case r == ':':
			l.emit(tokColon)
		case r == ',':
			l.emit(tokComma)
		case r == '\'' || r == '"':
			l.backup()
			return varLexString
		case r == '@':
			l.backup()
			return varLexType
		case unicode.IsSpace(r):
			l.ignore()
		case unicode.IsNumber(r) || r == '+' || r == '-':
			l.backup()
			return varLexNumber
		case r == 'b':
			pos := l.start
			if n := l.peek(); n == '"' || n == '\'' {
				return varLexByteString
			}
			// not a byte string; try to parse it as a type or bool below
			l.pos = pos + 1
			l.width = 1
			fallthrough
		default:
			// either a bool or a type. Try bools first.
			l.backup()
			if l.pos+4 <= len(l.input) {
				if l.input[l.pos:l.pos+4] == "true" {
					l.pos += 4
					l.emit(tokBool)
					continue
				}
			}
			if l.pos+5 <= len(l.input) {
				if l.input[l.pos:l.pos+5] == "false" {
					l.pos += 5
					l.emit(tokBool)
					continue
				}
			}
			// must be a type.
			return varLexType
		}
	}
}

var varTypeMap = map[string]string{
	"boolean":    "b",
	"byte":       "y",
	"int16":      "n",
	"uint16":     "q",
	"int32":      "i",
	"uint32":     "u",
	"int64":      "x",
	"uint64":     "t",
	"double":     "f",
	"string":     "s",
	"objectpath": "o",
	"signature":  "g",
}

func varLexByteString(l *varLexer) lexState {
	q := l.next()
Loop:
	for {
		switch l.next() {
		case '\\':
			if r := l.next(); r != -1 {
				break
			}
			fallthrough
		case -1:
			return l.errorf("unterminated bytestring")
		case q:
			break Loop
		}
	}
	l.emit(tokByteString)
	return varLexNormal
}

func varLexNumber(l *varLexer) lexState {
	l.accept("+-")
	digits := "0123456789"
	if l.accept("0") {
		if l.accept("x") {
			digits = "0123456789abcdefABCDEF"
		} else {
			digits = "01234567"
		}
	}
	for strings.IndexRune(digits, l.next()) >= 0 {
	}
	l.backup()
	if l.accept(".") {
		for strings.IndexRune(digits, l.next()) >= 0 {
		}
		l.backup()
	}
	if l.accept("eE") {
		l.accept("+-")
		for strings.IndexRune("0123456789", l.next()) >= 0 {
		}
		l.backup()
	}
	if r := l.peek(); unicode.IsLetter(r) {
		l.next()
		return l.errorf("bad number syntax: %q", l.input[l.start:l.pos])
	}
	l.emit(tokNumber)
	return varLexNormal
}

func varLexString(l *varLexer) lexState {
	q := l.next()
Loop:
	for {
		switch l.next() {
		case '\\':
			if r := l.next(); r != -1 {
				break
			}
			fallthrough
		case -1:
			return l.errorf("unterminated string")
		case q:
			break Loop
		}
	}
	l.emit(tokString)
	return varLexNormal
}

func varLexType(l *varLexer) lexState {
	at := l.accept("@")
	for {
		r := l.next()
		if r == -1 {
			break
		}
		if unicode.IsSpace(r) {
			l.backup()
			break
		}
	}
	if at {
		if _, err := ParseSignature(l.input[l.start+1 : l.pos]); err != nil {
			return l.errorf("%s", err)
		}
	} else {
		if _, ok := varTypeMap[l.input[l.start:l.pos]]; ok {
			l.emit(tokType)
			return varLexNormal
		}
		return l.errorf("unrecognized type %q", l.input[l.start:l.pos])
	}
	l.emit(tokType)
	return varLexNormal
}
