// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package parse

import (
	"errors"
	"fmt"
	"runtime"
)

var (
	// ParseErrorLimit is the maximum number of errors before a parse is aborted.
	ParseErrorLimit = 10
	// AbortParse is paniced when a parse cannot continue. It is recovered at the
	// top level, to allow the errors to be cleanly returned to the caller.
	AbortParse = errors.New("abort")
)

// Error represents the information that us useful in debugging a parse failure.
type Error struct {
	// At is the parse fragment that was being processed when the error was encountered.
	At Fragment
	// Message is the message associated with the error.
	Message string
	// Stack is the captured stack trace at the point the error was noticed.
	Stack []byte
}

// ErrorList is a convenience type for managing lists of errors.
type ErrorList []Error

func (errs ErrorList) Error() string {
	if len(errs) == 0 {
		return ""
	}
	return fmt.Sprintf("%d errors, first error was: %v", len(errs), errs[0])
}

func (err Error) Error() string {
	return err.Message
}

func (err Error) Format(f fmt.State, c rune) {
	line, column := err.At.Token().Cursor()
	fmt.Fprintf(f, "%v:%v: %s", line, column, err.Message)
}

func (l *ErrorList) Add(r *Reader, at Fragment, message string, args ...interface{}) {
	if len(*l) >= ParseErrorLimit {
		panic(AbortParse)
	}
	err := Error{At: at}
	if at == nil || at.Token().Len() == 0 {
		invalid := &fragment{}
		if r != nil {
			invalid.SetToken(r.GuessNextToken())
			err.At = invalid
		}
	}
	if len(args) > 0 {
		err.Message = fmt.Sprintf(message, args...)
	} else {
		err.Message = message
	}
	var stack [1 << 16]byte
	size := runtime.Stack(stack[:], false)
	err.Stack = make([]byte, size)
	copy(err.Stack, stack[:size])
	*l = append(*l, err)
}
