// 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/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...)
}
