// Copyright 2021 The Fuchsia 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 main

import (
	"regexp"
	"strconv"
	"strings"

	"github.com/alecthomas/participle/v2"
	"github.com/alecthomas/participle/v2/lexer"
)

// This file is based on the official FIDL grammar:
// https://fuchsia.dev/fuchsia-src/reference/fidl/language/grammar
//
// It uses the participle parser library:
// https://github.com/alecthomas/participle
//
// A quick primer on participle:
//
// - It has separate lexing and parsing stages.
// - Lexer tokens are defined by regexes.
// - Productions are defined by structs with tags on each field.
// - The tags get concatenated (e.g. parens can be unbalanced within a tag).
// - Tags have the format `<exp1> <exp2> ... <expN>`.
// - Expression `"foo"` matches the literal "foo".
// - Expression `Foo` matches a Foo token.
// - Expression `@<exp>` captures <exp> into the field.
// - Expression `@@` recursively captures based on the field's type.
// - Tags for slice types can have multiple captures.
// - Boolean fields become true if a capture occurred.
// - Parentheses, `?`, `+`, `*`, `|` behave as expected.

var (
	fidlLexer = lexer.MustSimple([]lexer.Rule{
		{Name: "Whitespace", Pattern: `[ \n\r\t]`},
		{Name: "Comment", Pattern: `//[^\n]*`},
		{Name: "Punctuation", Pattern: "[.,;@=()]"},
		{Name: "String", Pattern: `"(\\.|[^"\\])*"`},
		// This pattern matches the FIDL lexer, which defers more precise
		// numeric parsing to the flat AST stage.
		{Name: "Number", Pattern: `[0-9][0-9a-fA-FxX._\-]*`},
		// https://fuchsia.dev/fuchsia-src/reference/fidl/language/language?hl=en#identifiers
		{Name: "Identifier", Pattern: `[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?`},
		// Define a fallback token so that the lexer never fails and we can
		// ignore the rest of the file (see the Rest field in fidlTopLevel).
		{Name: "Other", Pattern: `.*`},
	})

	fidlParser = participle.MustBuild(
		&fidlTopLevel{},
		participle.Lexer(fidlLexer),
		participle.Elide("Whitespace", "Comment"),
	)
)

type fidlTopLevel struct {
	Header fidlLibraryHeader `@@`
	Using  []fidlUsing       `@@*`
	// Ignore the rest of the file by matching 0+ tokens of any kind. Rather
	// than list every token type, we say ~"" (anything not equal to "").
	Rest bool `(@~"")*`
}

type fidlLibraryHeader struct {
	Attributes []fidlAttribute        `@@*`
	Library    fidlCompoundIdentifier `"library" @@ ";"`
}

type fidlUsing struct {
	Library fidlCompoundIdentifier `"using" @@`
	Alias   bool                   `("as" @Identifier)? ";"`
}

type fidlAttribute struct {
	Name bool               `"@" @Identifier`
	Args []fidlAttributeArg `("(" @@ ("," @@)* ")")?`
}

type fidlAttributeArg struct {
	Name  bool         `(@Identifier "=")?`
	Value fidlConstant `@@`
}

type fidlConstant struct {
	Identifier *fidlCompoundIdentifier `@@`
	Literal    bool                    `| @String | @Number | "true" | "false"`
}

type fidlCompoundIdentifier struct {
	// Note: The field must be named "Pos" for participle to recognize it.
	Pos   lexer.Position
	Parts []string `@Identifier ("." @Identifier)*`
}

// Note: fields exported for cmp.Diff.
type parsedFidl struct {
	Decl  parsedLibrary
	Using []parsedLibrary
}

// Note: fields exported for cmp.Diff.
type parsedLibrary struct {
	Library      library
	Line, Column int
}

func parseFidl(input string) (parsedFidl, error) {
	var (
		top      fidlTopLevel
		parsed   parsedFidl
		filename = ""
	)
	err := fidlParser.ParseString(filename, input, &top)
	if err != nil {
		return parsed, err
	}
	parsed.Decl = toParsedLibrary(top.Header.Library)
	for _, using := range top.Using {
		parsed.Using = append(parsed.Using, toParsedLibrary(using.Library))
	}
	return parsed, nil
}

func toParsedLibrary(ident fidlCompoundIdentifier) parsedLibrary {
	return parsedLibrary{
		Library: library(strings.Join(ident.Parts, ".")),
		Line:    ident.Pos.Line,
		Column:  ident.Pos.Column,
	}
}

func (m *parsedLibrary) annotation(kind annotationKind, text string) annotation {
	return annotation{
		Line:   m.Line,
		Column: m.Column,
		Kind:   kind,
		Text:   text,
	}
}

var fidlAnnotationRegexp = regexp.MustCompile(`` +
	// Multi-line mode: ^ and $ match begin/end of line OR text.
	`(?m)` +
	`^/.*/fidlbolt\.fidl:(\d+):(\d+).*?` +
	`(` +
	string(Info) + `|` +
	string(Warning) + `|` +
	string(Error) + `)` +
	`:\s*(.*)$`)

// parseFidlAnnotations parses a list of annotations from error output. It
// assumes that the output refers to a file called "fidlbolt.fidl".
// TODO: Use fidlc --format=json instead of regex parsing.
func parseFidlAnnotations(output string) []annotation {
	matches := fidlAnnotationRegexp.FindAllStringSubmatch(output, -1)
	var anns []annotation
	for _, m := range matches {
		line, err := strconv.Atoi(m[1])
		if err != nil {
			continue
		}
		column, err := strconv.Atoi(m[2])
		if err != nil {
			continue
		}
		anns = append(anns, annotation{
			Line:   line,
			Column: column,
			Kind:   annotationKind(m[3]),
			Text:   m[4],
		})
	}
	return anns
}
