// Copyright 2019 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 tap

import (
	"errors"
	"fmt"
	"log"
	"strconv"
	"strings"

	"go.fuchsia.dev/tools/testing/tap/tokenizer"
)

// Parse parses the given input string into a Document. The input is allowed to contain
// garbage lines; The parser will skip them and parse as much of the input as possible.
// The only execption is that the first line of input must be a TAP version header of the
// form "TAP version XXX".
func Parse(input []byte) (*Document, error) {
	output := make(chan *Document)
	go parse(tokenizer.NewTokenStream(input), output)
	return <-output, nil
}

// State represents a parser state. Each state takes the current stream of input tokens
// and the current Document and attempts to parse the next line of input. A state must
// return the next state to use, even when an error is encountered. If nil is returned,
// parsing stops.
type state func(*tokenizer.TokenStream, *Document) (state, error)

// Parse parses a Document from the given Token stream. The result is emitted on the
// output channel.
func parse(tokens *tokenizer.TokenStream, output chan<- *Document) {
	document := &Document{}

	for state := parseVersion; state != nil; {
		next, err := state(tokens, document)
		if err != nil {
			// Garbage lines are allowed; Treat errors as non-fatal.
			log.Println(err)
		}
		state = next
	}

	output <- document
}

// DiscardLine is a parser state that throws away every token until a newline or EOF.
func discardLine(tokens *tokenizer.TokenStream, _ *Document) (state, error) {
	for {
		token := tokens.Peek()
		switch {
		case token.Type == tokenizer.TypeEOF:
			return nil, nil
		case token.Type != tokenizer.TypeNewline:
			tokens.Next()
		default:
			tokens.Next() // Skip the newline.
			return parseNextLine, nil
		}
	}
}

func parseNextLine(tokens *tokenizer.TokenStream, doc *Document) (state, error) {
	rtokens := tokens.Raw()
	if rtokens.Peek().Type == tokenizer.TypeEOF {
		return nil, nil
	}

	if rtokens.Peek().Type == tokenizer.TypeSpace {
		return parseYAMLBlock, nil
	}

	if rtokens.Peek().Type == tokenizer.TypeNumber {
		return parsePlan, nil
	}

	if rtokens.Peek().Value == "ok" || rtokens.Peek().Value == "not" {
		return parseTestLine, nil
	}

	return parseNextLine, unexpectedTokenError("one of 'ok', 'not' or a number", tokens.Next())
}

func parseVersion(tokens *tokenizer.TokenStream, doc *Document) (state, error) {
	token := tokens.Next()
	if token.Value != "TAP" {
		return nil, unexpectedTokenError("'TAP'", token)
	}

	token = tokens.Next()
	if token.Value != "version" {
		return nil, unexpectedTokenError("'version'", token)
	}

	token = tokens.Next()
	if token.Type != tokenizer.TypeNumber {
		return nil, unexpectedTokenError("a version number", token)
	}

	version, err := strconv.ParseInt(token.Value, 10, 64)
	if err != nil {
		return nil, parserError(err.Error())
	}

	doc.Version = Version(version)
	return parseNextLine, tokens.Eat(tokenizer.TypeNewline)
}

func parsePlan(tokens *tokenizer.TokenStream, doc *Document) (state, error) {
	if doc.Plan.Start != 0 || doc.Plan.End != 0 {
		return discardLine, errors.New("plan has already been parsed")
	}

	token := tokens.Peek()
	if token.Type != tokenizer.TypeNumber {
		return discardLine, unexpectedTokenError("a number", token)
	}

	start, err := strconv.ParseInt(tokens.Next().Value, 10, 64)
	if err != nil {
		return discardLine, parserError(err.Error())
	}

	if err := tokens.Eat(tokenizer.TypeDot); err != nil {
		return discardLine, err
	}

	if err := tokens.Eat(tokenizer.TypeDot); err != nil {
		return discardLine, err
	}

	token = tokens.Peek()
	if token.Type != tokenizer.TypeNumber {
		return discardLine, unexpectedTokenError("a number > 1", token)
	}

	end, err := strconv.ParseInt(tokens.Next().Value, 10, 64)
	if err != nil {
		return discardLine, parserError(err.Error())
	}

	doc.Plan = Plan{Start: int(start), End: int(end)}
	return parseNextLine, tokens.Eat(tokenizer.TypeNewline)
}

func parseTestLine(tokens *tokenizer.TokenStream, doc *Document) (state, error) {
	var testLine TestLine

	// Parse test status.
	token := tokens.Next()
	switch token.Value {
	case "not":
		testLine.Ok = false
		token = tokens.Next()
		if token.Value != "ok" {
			return discardLine, unexpectedTokenError("'ok'", token)
		}
	case "ok":
		testLine.Ok = true
	default:
		return discardLine, unexpectedTokenError("'ok' or 'not ok'", token)
	}

	// Parse optional test number.
	testLine.Count = len(doc.TestLines) + 1
	if tokens.Peek().Type == tokenizer.TypeNumber {
		count, err := strconv.ParseInt(tokens.Next().Value, 10, 64)
		if err != nil {
			return discardLine, parserError(err.Error())
		}
		testLine.Count = int(count)
	}

	// Parse optional description. Stop at a TypePound token which marks the start of a
	// diagnostic.
	description := tokens.Raw().ConcatUntil(tokenizer.TypePound, tokenizer.TypeNewline)
	testLine.Description = strings.TrimSpace(description)

	switch tokens.Peek().Type {
	case tokenizer.TypeEOF:
		doc.TestLines = append(doc.TestLines, testLine)
		return nil, nil
	case tokenizer.TypeNewline:
		doc.TestLines = append(doc.TestLines, testLine)
		return discardLine, nil
	case tokenizer.TypePound:
		tokens.Eat(tokenizer.TypePound)
	}

	// Parse optional directive.
	token = tokens.Next()
	switch token.Value {
	case "TODO":
		testLine.Directive = Todo
	case "SKIP":
		testLine.Directive = Skip
	default:
		return discardLine, unexpectedTokenError("a directive", token)
	}

	// Parse explanation.
	explanation := tokens.Raw().ConcatUntil(tokenizer.TypeNewline)
	testLine.Explanation = strings.TrimSpace(explanation)
	doc.TestLines = append(doc.TestLines, testLine)

	if tokens.Peek().Type == tokenizer.TypeEOF {
		return nil, nil
	}
	tokens.Eat(tokenizer.TypeNewline)
	return parseNextLine, nil
}

// Parses a YAML block. The block must begin as a line containing three dashes and end
// with a line containing three dots.
func parseYAMLBlock(tokens *tokenizer.TokenStream, doc *Document) (state, error) {
	rtokens := tokens.Raw()
	if len(doc.TestLines) == 0 {
		return discardLine, parserError("found YAML with no parent test line")
	}
	testLine := &doc.TestLines[len(doc.TestLines)-1]
	if len(testLine.YAML) > 0 {
		return discardLine, parserError("found YAML with no parent test line")
	}

	// Expect the header to match /\s+---/
	header := rtokens.ConcatUntil(tokenizer.TypeNewline)
	if len(header) < 4 || !strings.HasPrefix(strings.TrimSpace(header), "---") {
		return discardLine, fmt.Errorf("expected line matching /^\\s+---/ but got %q", header)
	}
	if err := rtokens.Eat(tokenizer.TypeNewline); err != nil {
		return discardLine, unexpectedTokenError("a newline", rtokens.Peek())
	}

	var body string
	for {
		line := rtokens.ConcatUntil(tokenizer.TypeNewline)
		// Expect the footer to match /\s+.../
		if len(line) >= 4 && strings.HasPrefix(strings.TrimSpace(line), "...") {
			break
		}

		body += strings.TrimSpace(line) + "\n"
		if rtokens.Peek().Type == tokenizer.TypeEOF {
			break
		}
		rtokens.Eat(tokenizer.TypeNewline)
	}

	testLine.YAML = body
	return parseNextLine, nil
}

func unexpectedTokenError(wanted string, token tokenizer.Token) error {
	return parserError("got %q but wanted %s", token, wanted)
}

func parserError(format string, args ...interface{}) error {
	return fmt.Errorf("parse error: "+format, args...)
}
