// Copyright 2018 The CUE Authors
//
// 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.

// This file contains the exported entry points for invoking the

package parser

import (
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal/source"
)

// Option specifies a parse option.
type Option func(p *parser)

var (
	// PackageClauseOnly causes parsing to stop after the package clause.
	PackageClauseOnly Option = packageClauseOnly
	packageClauseOnly        = func(p *parser) {
		p.mode |= packageClauseOnlyMode
	}

	// ImportsOnly causes parsing to stop parsing after the import declarations.
	ImportsOnly Option = importsOnly
	importsOnly        = func(p *parser) {
		p.mode |= importsOnlyMode
	}

	// ParseComments causes comments to be parsed.
	ParseComments Option = parseComments
	parseComments        = func(p *parser) {
		p.mode |= parseCommentsMode
	}

	// Trace causes parsing to print a trace of parsed productions.
	Trace    Option = traceOpt
	traceOpt        = func(p *parser) {
		p.mode |= traceMode
	}

	// DeclarationErrors causes parsing to report declaration errors.
	DeclarationErrors Option = declarationErrors
	declarationErrors        = func(p *parser) {
		p.mode |= declarationErrorsMode
	}

	// AllErrors causes all errors to be reported (not just the first 10 on different lines).
	AllErrors Option = allErrors
	allErrors        = func(p *parser) {
		p.mode |= allErrorsMode
	}

	// AllowPartial allows the parser to be used on a prefix buffer.
	AllowPartial Option = allowPartial
	allowPartial        = func(p *parser) {
		p.mode |= partialMode
	}
)

// FromVersion specifies until which legacy version the parser should provide
// backwards compatibility.
func FromVersion(version int) Option {
	if version >= 0 {
		version++
	}
	// Versions:
	// <0:  major version 0 (counting -1000 + x, where x = 100*m+p in 0.m.p
	// >=0: x+1 in 1.x.y
	return func(p *parser) { p.version = version }
}

func version0(minor, patch int) int {
	return -1000 + 100*minor + patch
}

// DeprecationError is a sentinel error to indicate that an error is
// related to an unsupported old CUE syntax.
type DeprecationError struct {
	Version int
}

func (e *DeprecationError) Error() string {
	return "try running `cue fix` on the file or module to upgrade"
}

// Latest specifies the latest version of the parser, effectively setting
// the strictest implementation.
const Latest = latest

const latest = 1000

// FileOffset specifies the File position info to use.
func FileOffset(pos int) Option {
	return func(p *parser) { p.offset = pos }
}

// A mode value is a set of flags (or 0).
// They control the amount of source code parsed and other optional
// parser functionality.
type mode uint

const (
	packageClauseOnlyMode mode = 1 << iota // stop parsing after package clause
	importsOnlyMode                        // stop parsing after import declarations
	parseCommentsMode                      // parse comments and add them to AST
	partialMode
	traceMode             // print a trace of parsed productions
	declarationErrorsMode // report declaration errors
	allErrorsMode         // report all errors (not just the first 10 on different lines)
)

// ParseFile parses the source code of a single CUE source file and returns
// the corresponding File node. The source code may be provided via
// the filename of the source file, or via the src parameter.
//
// If src != nil, ParseFile parses the source from src and the filename is
// only used when recording position information. The type of the argument
// for the src parameter must be string, []byte, or io.Reader.
// If src == nil, ParseFile parses the file specified by filename.
//
// The mode parameter controls the amount of source text parsed and other
// optional parser functionality. Position information is recorded in the
// file set fset, which must not be nil.
//
// If the source couldn't be read, the returned AST is nil and the error
// indicates the specific failure. If the source was read but syntax
// errors were found, the result is a partial AST (with Bad* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a ErrorList which is sorted by file position.
func ParseFile(filename string, src interface{}, mode ...Option) (f *ast.File, err error) {

	// get source
	text, err := source.Read(filename, src)
	if err != nil {
		return nil, err
	}

	var pp parser
	defer func() {
		if pp.panicking {
			_ = recover()
		}

		// set result values
		if f == nil {
			// source is not a valid Go source file - satisfy
			// ParseFile API and return a valid (but) empty
			// *File
			f = &ast.File{
				// Scope: NewScope(nil),
			}
		}

		err = errors.Sanitize(pp.errors)
	}()

	// parse source
	pp.init(filename, text, mode)
	f = pp.parseFile()
	if f == nil {
		return nil, pp.errors
	}
	f.Filename = filename
	astutil.Resolve(f, pp.errf)

	return f, pp.errors
}

// ParseExpr is a convenience function for parsing an expression.
// The arguments have the same meaning as for Parse, but the source must
// be a valid CUE (type or value) expression. Specifically, fset must not
// be nil.
func ParseExpr(filename string, src interface{}, mode ...Option) (ast.Expr, error) {
	// get source
	text, err := source.Read(filename, src)
	if err != nil {
		return nil, err
	}

	var p parser
	defer func() {
		if p.panicking {
			_ = recover()
		}
		err = errors.Sanitize(p.errors)
	}()

	// parse expr
	p.init(filename, text, mode)
	// Set up pkg-level scopes to avoid nil-pointer errors.
	// This is not needed for a correct expression x as the
	// parser will be ok with a nil topScope, but be cautious
	// in case of an erroneous x.
	e := p.parseRHS()

	// If a comma was inserted, consume it;
	// report an error if there's more tokens.
	if p.tok == token.COMMA && p.lit == "\n" {
		p.next()
	}
	if p.mode&partialMode == 0 {
		p.expect(token.EOF)
	}

	if p.errors != nil {
		return nil, p.errors
	}
	astutil.ResolveExpr(e, p.errf)

	return e, p.errors
}

// parseExprString is a convenience function for obtaining the AST of an
// expression x. The position information recorded in the AST is undefined. The
// filename used in error messages is the empty string.
func parseExprString(x string) (ast.Expr, error) {
	return ParseExpr("", []byte(x))
}
