// 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 (
	"fmt"

	"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 fmt.Sprintf("try running `cue fmt` on the file 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
}

// 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, nil
}

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