// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package ast

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strconv"
	"strings"
)

// Parse parses sys description into AST and returns top-level nodes.
// If any errors are encountered, returns nil.
func Parse(data []byte, filename string, errorHandler ErrorHandler) *Description {
	p := &parser{s: newScanner(data, filename, errorHandler)}
	prevNewLine, prevComment := false, false
	var top []Node
	for p.next(); p.tok != tokEOF; {
		decl := p.parseTopRecover()
		if decl == nil {
			continue
		}
		// Add new lines around structs, remove duplicate new lines.
		if _, ok := decl.(*NewLine); ok && prevNewLine {
			continue
		}
		if str, ok := decl.(*Struct); ok && !prevNewLine && !prevComment {
			top = append(top, &NewLine{Pos: str.Pos})
		}
		top = append(top, decl)
		if str, ok := decl.(*Struct); ok {
			decl = &NewLine{Pos: str.Pos}
			top = append(top, decl)
		}
		_, prevNewLine = decl.(*NewLine)
		_, prevComment = decl.(*Comment)
	}
	if prevNewLine {
		top = top[:len(top)-1]
	}
	if !p.s.Ok() {
		return nil
	}
	return &Description{top}
}

func ParseGlob(glob string, errorHandler ErrorHandler) *Description {
	if errorHandler == nil {
		errorHandler = LoggingHandler
	}
	files, err := filepath.Glob(glob)
	if err != nil {
		errorHandler(Pos{}, fmt.Sprintf("failed to find input files: %v", err))
		return nil
	}
	if len(files) == 0 {
		errorHandler(Pos{}, fmt.Sprintf("no files matched by glob %q", glob))
		return nil
	}
	desc := &Description{}
	for _, f := range files {
		data, err := ioutil.ReadFile(f)
		if err != nil {
			errorHandler(Pos{}, fmt.Sprintf("failed to read input file: %v", err))
			return nil
		}
		desc1 := Parse(data, filepath.Base(f), errorHandler)
		if desc1 == nil {
			desc = nil
		}
		if desc != nil {
			desc.Nodes = append(desc.Nodes, desc1.Nodes...)
		}
	}
	return desc
}

type parser struct {
	s *scanner

	// Current token:
	tok token
	lit string
	pos Pos
}

// Skip parsing till the next NEWLINE, for error recovery.
var errSkipLine = errors.New("")

func (p *parser) parseTopRecover() Node {
	defer func() {
		switch err := recover(); err {
		case nil:
		case errSkipLine:
			// Try to recover by consuming everything until next NEWLINE.
			for p.tok != tokNewLine && p.tok != tokEOF {
				p.next()
			}
			p.tryConsume(tokNewLine)
		default:
			panic(err)
		}
	}()
	decl := p.parseTop()
	if decl == nil {
		panic("not reachable")
	}
	p.consume(tokNewLine)
	return decl
}

func (p *parser) parseTop() Node {
	switch p.tok {
	case tokNewLine:
		return &NewLine{Pos: p.pos}
	case tokComment:
		return p.parseComment()
	case tokDefine:
		return p.parseDefine()
	case tokInclude:
		return p.parseInclude()
	case tokIncdir:
		return p.parseIncdir()
	case tokResource:
		return p.parseResource()
	case tokIdent:
		name := p.parseIdent()
		if name.Name == "type" {
			return p.parseTypeDef()
		}
		switch p.tok {
		case tokLParen:
			return p.parseCall(name)
		case tokLBrace, tokLBrack:
			return p.parseStruct(name)
		case tokEq:
			return p.parseFlags(name)
		default:
			p.expect(tokLParen, tokLBrace, tokLBrack, tokEq)
		}
	case tokIllegal:
		// Scanner has already producer an error for this one.
		panic(errSkipLine)
	default:
		p.expect(tokComment, tokDefine, tokInclude, tokResource, tokIdent)
	}
	panic("not reachable")
}

func (p *parser) next() {
	p.tok, p.lit, p.pos = p.s.Scan()
}

func (p *parser) consume(tok token) {
	p.expect(tok)
	p.next()
}

func (p *parser) tryConsume(tok token) bool {
	if p.tok != tok {
		return false
	}
	p.next()
	return true
}

func (p *parser) expect(tokens ...token) {
	for _, tok := range tokens {
		if p.tok == tok {
			return
		}
	}
	var str []string
	for _, tok := range tokens {
		str = append(str, tok.String())
	}
	p.s.Error(p.pos, fmt.Sprintf("unexpected %v, expecting %v", p.tok, strings.Join(str, ", ")))
	panic(errSkipLine)
}

func (p *parser) parseComment() *Comment {
	c := &Comment{
		Pos:  p.pos,
		Text: p.lit,
	}
	p.consume(tokComment)
	return c
}

func (p *parser) parseDefine() *Define {
	pos0 := p.pos
	p.consume(tokDefine)
	name := p.parseIdent()
	p.expect(tokInt, tokIdent, tokCExpr)
	var val *Int
	if p.tok == tokCExpr {
		val = p.parseCExpr()
	} else {
		val = p.parseInt()
	}
	return &Define{
		Pos:   pos0,
		Name:  name,
		Value: val,
	}
}

func (p *parser) parseInclude() *Include {
	pos0 := p.pos
	p.consume(tokInclude)
	return &Include{
		Pos:  pos0,
		File: p.parseString(),
	}
}

func (p *parser) parseIncdir() *Incdir {
	pos0 := p.pos
	p.consume(tokIncdir)
	return &Incdir{
		Pos: pos0,
		Dir: p.parseString(),
	}
}

func (p *parser) parseResource() *Resource {
	pos0 := p.pos
	p.consume(tokResource)
	name := p.parseIdent()
	p.consume(tokLBrack)
	base := p.parseType()
	p.consume(tokRBrack)
	var values []*Int
	if p.tryConsume(tokColon) {
		values = append(values, p.parseInt())
		for p.tryConsume(tokComma) {
			values = append(values, p.parseInt())
		}
	}
	return &Resource{
		Pos:    pos0,
		Name:   name,
		Base:   base,
		Values: values,
	}
}

func (p *parser) parseTypeDef() *TypeDef {
	pos0 := p.pos
	name := p.parseIdent()
	var typ *Type
	var str *Struct
	var args []*Ident
	p.expect(tokLBrack, tokIdent)
	if p.tryConsume(tokLBrack) {
		args = append(args, p.parseIdent())
		for p.tryConsume(tokComma) {
			args = append(args, p.parseIdent())
		}
		p.consume(tokRBrack)
		if p.tok == tokLBrace || p.tok == tokLBrack {
			emptyName := &Ident{
				Pos:  pos0,
				Name: "",
			}
			str = p.parseStruct(emptyName)
		} else {
			typ = p.parseType()
		}
	} else {
		typ = p.parseType()
	}
	return &TypeDef{
		Pos:    pos0,
		Name:   name,
		Args:   args,
		Type:   typ,
		Struct: str,
	}
}

func (p *parser) parseCall(name *Ident) *Call {
	c := &Call{
		Pos:      name.Pos,
		Name:     name,
		CallName: callName(name.Name),
	}
	p.consume(tokLParen)
	for p.tok != tokRParen {
		c.Args = append(c.Args, p.parseField())
		p.expect(tokComma, tokRParen)
		p.tryConsume(tokComma)
	}
	p.consume(tokRParen)
	if p.tok != tokNewLine {
		c.Ret = p.parseType()
	}
	return c
}

func callName(s string) string {
	pos := strings.IndexByte(s, '$')
	if pos == -1 {
		return s
	}
	return s[:pos]
}

func (p *parser) parseFlags(name *Ident) Node {
	p.consume(tokEq)
	switch p.tok {
	case tokInt, tokIdent:
		return p.parseIntFlags(name)
	case tokString:
		return p.parseStrFlags(name)
	default:
		p.expect(tokInt, tokIdent, tokString)
		return nil
	}
}

func (p *parser) parseIntFlags(name *Ident) *IntFlags {
	values := []*Int{p.parseInt()}
	for p.tryConsume(tokComma) {
		values = append(values, p.parseInt())
	}
	return &IntFlags{
		Pos:    name.Pos,
		Name:   name,
		Values: values,
	}
}

func (p *parser) parseStrFlags(name *Ident) *StrFlags {
	values := []*String{p.parseString()}
	for p.tryConsume(tokComma) {
		values = append(values, p.parseString())
	}
	return &StrFlags{
		Pos:    name.Pos,
		Name:   name,
		Values: values,
	}
}

func (p *parser) parseStruct(name *Ident) *Struct {
	str := &Struct{
		Pos:  name.Pos,
		Name: name,
	}
	closing := tokRBrace
	if p.tok == tokLBrack {
		str.IsUnion = true
		closing = tokRBrack
	}
	p.next()
	p.consume(tokNewLine)
	for {
		newBlock := false
		for p.tok == tokNewLine {
			newBlock = true
			p.next()
		}
		comments := p.parseCommentBlock()
		if p.tryConsume(closing) {
			str.Comments = comments
			break
		}
		fld := p.parseField()
		fld.NewBlock = newBlock
		fld.Comments = comments
		str.Fields = append(str.Fields, fld)
		p.consume(tokNewLine)
	}
	if p.tryConsume(tokLBrack) {
		str.Attrs = append(str.Attrs, p.parseType())
		for p.tryConsume(tokComma) {
			str.Attrs = append(str.Attrs, p.parseType())
		}
		p.consume(tokRBrack)
	}
	return str
}

func (p *parser) parseCommentBlock() []*Comment {
	var comments []*Comment
	for p.tok == tokComment {
		comments = append(comments, p.parseComment())
		p.consume(tokNewLine)
		for p.tryConsume(tokNewLine) {
		}
	}
	return comments
}

func (p *parser) parseField() *Field {
	name := p.parseIdent()
	return &Field{
		Pos:  name.Pos,
		Name: name,
		Type: p.parseType(),
	}
}

func (p *parser) parseType() *Type {
	arg := &Type{
		Pos: p.pos,
	}
	allowColon := false
	switch p.tok {
	case tokInt:
		allowColon = true
		arg.Value, arg.ValueFmt = p.parseIntValue()
	case tokIdent:
		allowColon = true
		arg.Ident = p.lit
	case tokString:
		arg.String = p.lit
		arg.HasString = true
	default:
		p.expect(tokInt, tokIdent, tokString)
	}
	p.next()
	if allowColon && p.tryConsume(tokColon) {
		arg.HasColon = true
		arg.Pos2 = p.pos
		switch p.tok {
		case tokInt:
			arg.Value2, arg.Value2Fmt = p.parseIntValue()
		case tokIdent:
			arg.Ident2 = p.lit
		default:
			p.expect(tokInt, tokIdent)
		}
		p.next()
	}
	arg.Args = p.parseTypeList()
	return arg
}

func (p *parser) parseTypeList() []*Type {
	var args []*Type
	if p.tryConsume(tokLBrack) {
		args = append(args, p.parseType())
		for p.tryConsume(tokComma) {
			args = append(args, p.parseType())
		}
		p.consume(tokRBrack)
	}
	return args
}

func (p *parser) parseIdent() *Ident {
	p.expect(tokIdent)
	ident := &Ident{
		Pos:  p.pos,
		Name: p.lit,
	}
	p.next()
	return ident
}

func (p *parser) parseString() *String {
	p.expect(tokString)
	str := &String{
		Pos:   p.pos,
		Value: p.lit,
	}
	p.next()
	return str
}

func (p *parser) parseInt() *Int {
	i := &Int{
		Pos: p.pos,
	}
	switch p.tok {
	case tokInt:
		i.Value, i.ValueFmt = p.parseIntValue()
	case tokIdent:
		i.Ident = p.lit
	default:
		p.expect(tokInt, tokIdent)
	}
	p.next()
	return i
}

func (p *parser) parseIntValue() (uint64, IntFmt) {
	if p.lit[0] == '\'' {
		return uint64(p.lit[1]), IntFmtChar
	}
	if v, err := strconv.ParseUint(p.lit, 10, 64); err == nil {
		return v, IntFmtDec
	}
	if v, err := strconv.ParseInt(p.lit, 10, 64); err == nil {
		return uint64(v), IntFmtNeg
	}
	if len(p.lit) > 2 && p.lit[0] == '0' && p.lit[1] == 'x' {
		if v, err := strconv.ParseUint(p.lit[2:], 16, 64); err == nil {
			return v, IntFmtHex
		}
	}
	panic(fmt.Sprintf("scanner returned bad integer %q", p.lit))
}

func (p *parser) parseCExpr() *Int {
	i := &Int{
		Pos:   p.pos,
		CExpr: p.lit,
	}
	p.consume(tokCExpr)
	return i
}
