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

package cue

import (
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal/core/adt"
	"cuelang.org/go/internal/core/compile"
	"cuelang.org/go/internal/core/convert"
	"cuelang.org/go/internal/core/debug"
	"cuelang.org/go/internal/core/eval"
	"cuelang.org/go/internal/core/runtime"
)

// A Context is used for creating CUE Values.
//
// A Context keeps track of loaded instances, indices of internal
// representations of values, and defines the set of supported builtins. Any
// operation that involves two Values should originate from the same Context.
//
// Use
//
//    ctx := cuecontext.New()
//
// to create a new Context.
type Context runtime.Runtime

func (c *Context) runtime() *runtime.Runtime {
	rt := (*runtime.Runtime)(c)
	return rt
}

func (c *Context) ctx() *adt.OpContext {
	return newContext(c.runtime())
}

// Context reports the Context with which this value was created.
func (v Value) Context() *Context {
	return (*Context)(v.idx)
}

// A BuildOption defines options for the various build-related methods of
// Context.
type BuildOption func(o *runtime.Config)

// Scope defines a context in which to resolve unresolved identifiers.
//
// Only one scope may be given. It panics if more than one scope is given
// or if the Context in which scope was created differs from the one where
// this option is used.
func Scope(scope Value) BuildOption {
	return func(o *runtime.Config) {
		if o.Runtime != scope.idx {
			panic("incompatible runtime")
		}
		if o.Scope != nil {
			panic("more than one scope is given")
		}
		o.Scope = valueScope(scope)
	}
}

// Filename assigns a filename to parsed content.
func Filename(filename string) BuildOption {
	return func(o *runtime.Config) { o.Filename = filename }
}

// InferBuiltins allows unresolved references to bind to builtin packages with a
// unique package name.
//
// This option is intended for evaluating expressions in a context where import
// statements cannot be used. It is not recommended to use this for evaluating
// CUE files.
func InferBuiltins(elide bool) BuildOption {
	return func(o *runtime.Config) {
		o.Imports = func(x *ast.Ident) (pkgPath string) {
			if !o.Runtime.IsBuiltinPackage(x.Name) {
				return ""
			}
			return x.Name
		}
	}
}

func (c *Context) parseOptions(options []BuildOption) (cfg runtime.Config) {
	cfg.Runtime = (*runtime.Runtime)(c)
	for _, f := range options {
		f(&cfg)
	}
	return cfg
}

// BuildInstance creates a Value from the given build.Instance.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) BuildInstance(i *build.Instance, options ...BuildOption) Value {
	cfg := c.parseOptions(options)
	v, err := c.runtime().Build(&cfg, i)
	if err != nil {
		return c.makeError(err)
	}
	return c.make(v)
}

func (c *Context) makeError(err errors.Error) Value {
	b := &adt.Bottom{Err: err}
	node := &adt.Vertex{BaseValue: b}
	node.UpdateStatus(adt.Finalized)
	node.AddConjunct(adt.MakeRootConjunct(nil, b))
	return c.make(node)
}

// BuildInstances creates a Value for each of the given instances and reports
// the combined errors or nil if there were no errors.
func (c *Context) BuildInstances(instances []*build.Instance) ([]Value, error) {
	var errs errors.Error
	var a []Value
	for _, b := range instances {
		v, err := c.runtime().Build(nil, b)
		if err != nil {
			errs = errors.Append(errs, err)
		}
		a = append(a, c.make(v))
	}
	return a, errs
}

// BuildFile creates a Value from f.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) BuildFile(f *ast.File, options ...BuildOption) Value {
	cfg := c.parseOptions(options)
	return c.compile(c.runtime().CompileFile(&cfg, f))
}

func (c *Context) compile(v *adt.Vertex, p *build.Instance) Value {
	if p.Err != nil {
		return c.makeError(p.Err)
	}
	return c.make(v)
}

// BuildExpr creates a Value from x.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) BuildExpr(x ast.Expr, options ...BuildOption) Value {
	r := c.runtime()
	cfg := c.parseOptions(options)

	ctx := c.ctx()

	astutil.ResolveExpr(x, errFn)
	conjunct, err := compile.Expr(&cfg.Config, r, anonymousPkg, x)
	if err != nil {
		return c.makeError(err)
	}
	v := adt.Resolve(ctx, conjunct)

	return c.make(v)
}

func errFn(pos token.Pos, msg string, args ...interface{}) {}

// resolveExpr binds unresolved expressions to values in the expression or v.
func resolveExpr(ctx *adt.OpContext, v Value, x ast.Expr) adt.Value {
	cfg := &compile.Config{Scope: valueScope(v)}

	astutil.ResolveExpr(x, errFn)

	c, err := compile.Expr(cfg, ctx, anonymousPkg, x)
	if err != nil {
		return &adt.Bottom{Err: err}
	}
	return adt.Resolve(ctx, c)
}

// anonymousPkg reports a package path that can never resolve to a valid package.
const anonymousPkg = "_"

// CompileString parses and build a Value from the given source string.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) CompileString(src string, options ...BuildOption) Value {
	cfg := c.parseOptions(options)
	return c.compile(c.runtime().Compile(&cfg, src))
}

// ParseString parses and build a Value from the given source bytes.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) CompileBytes(b []byte, options ...BuildOption) Value {
	cfg := c.parseOptions(options)
	return c.compile(c.runtime().Compile(&cfg, b))
}

// TODO: fs.FS or custom wrapper?
// // CompileFile parses and build a Value from the given source bytes.
// //
// // The returned Value will represent an error, accessible through Err, if any
// // error occurred.
// func (c *Context) CompileFile(f fs.File, options ...BuildOption) Value {
// 	b, err := io.ReadAll(f)
// 	if err != nil {
// 		return c.makeError(errors.Promote(err, "parsing file system file"))
// 	}
// 	return c.compile(c.runtime().Compile("", b))
// }

func (c *Context) make(v *adt.Vertex) Value {
	return newValueRoot(c.runtime(), newContext(c.runtime()), v)
}

// An EncodeOption defines options for the various encoding-related methods of
// Context.
type EncodeOption func(*encodeOptions)

type encodeOptions struct {
	nilIsTop bool
}

func (o *encodeOptions) process(option []EncodeOption) {
	for _, f := range option {
		f(o)
	}
}

// NilIsAny indicates whether a nil value is interpreted as null or _.
//
// The default is to interpret nil as _.
func NilIsAny(isAny bool) EncodeOption {
	return func(o *encodeOptions) { o.nilIsTop = isAny }
}

// Encode converts a Go value to a CUE value.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
//
// Encode traverses the value v recursively. If an encountered value implements
// the json.Marshaler interface and is not a nil pointer, Encode calls its
// MarshalJSON method to produce JSON and convert that to CUE instead. If no
// MarshalJSON method is present but the value implements encoding.TextMarshaler
// instead, Encode calls its MarshalText method and encodes the result as a
// string.
//
// Otherwise, Encode uses the following type-dependent default encodings:
//
// Boolean values encode as CUE booleans.
//
// Floating point, integer, and *big.Int and *big.Float values encode as CUE
// numbers.
//
// String values encode as CUE strings coerced to valid UTF-8, replacing
// sequences of invalid bytes with the Unicode replacement rune as per Unicode's
// and W3C's recommendation.
//
// Array and slice values encode as CUE lists, except that []byte encodes as a
// bytes value, and a nil slice encodes as the null.
//
// Struct values encode as CUE structs. Each exported struct field becomes a
// member of the object, using the field name as the object key, unless the
// field is omitted for one of the reasons given below.
//
// The encoding of each struct field can be customized by the format string
// stored under the "json" key in the struct field's tag. The format string
// gives the name of the field, possibly followed by a comma-separated list of
// options. The name may be empty in order to specify options without overriding
// the default field name.
//
// The "omitempty" option specifies that the field should be omitted from the
// encoding if the field has an empty value, defined as false, 0, a nil pointer,
// a nil interface value, and any empty array, slice, map, or string.
//
// See the documentation for Go's json.Marshal for more details on the field
// tags and their meaning.
//
// Anonymous struct fields are usually encoded as if their inner exported
// fields were fields in the outer struct, subject to the usual Go visibility
// rules amended as described in the next paragraph. An anonymous struct field
// with a name given in its JSON tag is treated as having that name, rather than
// being anonymous. An anonymous struct field of interface type is treated the
// same as having that type as its name, rather than being anonymous.
//
// The Go visibility rules for struct fields are amended for when deciding which
// field to encode or decode. If there are multiple fields at the same level,
// and that level is the least nested (and would therefore be the nesting level
// selected by the usual Go rules), the following extra rules apply:
//
// 1) Of those fields, if any are JSON-tagged, only tagged fields are
// considered, even if there are multiple untagged fields that would otherwise
// conflict.
//
// 2) If there is exactly one field (tagged or not according to the first rule),
// that is selected.
//
// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
//
// Map values encode as CUE structs. The map's key type must either be a string,
// an integer type, or implement encoding.TextMarshaler. The map keys are sorted
// and used as CUE struct field names by applying the following rules, subject
// to the UTF-8 coercion described for string values above:
//
//  - keys of any string type are used directly
//  - encoding.TextMarshalers are marshaled
//  - integer keys are converted to strings
//
// Pointer values encode as the value pointed to. A nil pointer encodes as the
// null CUE value.
//
// Interface values encode as the value contained in the interface. A nil
// interface value encodes as the null CUE value. The NilIsAny EncodingOption
// can be used to interpret nil as any (_) instead.
//
// Channel, complex, and function values cannot be encoded in CUE. Attempting to
// encode such a value results in the returned value being an error, accessible
// through the Err method.
//
func (c *Context) Encode(x interface{}, option ...EncodeOption) Value {
	switch v := x.(type) {
	case adt.Value:
		return newValueRoot(c.runtime(), c.ctx(), v)
	}
	var options encodeOptions
	options.process(option)

	ctx := c.ctx()
	// TODO: is true the right default?
	expr := convert.GoValueToValue(ctx, x, options.nilIsTop)
	n := &adt.Vertex{}
	n.AddConjunct(adt.MakeRootConjunct(nil, expr))
	n.Finalize(ctx)
	return c.make(n)
}

// Encode converts a Go type to a CUE value.
//
// The returned Value will represent an error, accessible through Err, if any
// error occurred.
func (c *Context) EncodeType(x interface{}, option ...EncodeOption) Value {
	switch v := x.(type) {
	case *adt.Vertex:
		return c.make(v)
	}

	ctx := c.ctx()
	expr, err := convert.GoTypeToExpr(ctx, x)
	if err != nil {
		return c.makeError(err)
	}
	n := &adt.Vertex{}
	n.AddConjunct(adt.MakeRootConjunct(nil, expr))
	n.Finalize(ctx)
	return c.make(n)
}

// NewList creates a Value that is a list of the given values.
//
// All Values must be created by c.
func (c *Context) NewList(v ...Value) Value {
	a := make([]adt.Value, len(v))
	for i, x := range v {
		if x.idx != (*runtime.Runtime)(c) {
			panic("values must be from same Context")
		}
		a[i] = x.v
	}
	return c.make(c.ctx().NewList(a...))
}

// TODO:

// func (c *Context) NewExpr(op Op, v ...Value) Value {
// 	return Value{}
// }

// func (c *Context) NewValue(v ...ValueElem) Value {
// 	return Value{}
// }

// func NewAttr(key string, values ...string) *Attribute {
// 	return &Attribute{}
// }

// // Clear unloads all previously-loaded imports.
// func (c *Context) Clear() {
// }

// // Values created up to the point of the Fork will be valid in both runtimes.
// func (c *Context) Fork() *Context {
// 	return nil
// }

// type ValueElem interface {
// }

// func NewField(sel Selector, value Value, attrs ...Attribute) ValueElem {
// 	return nil
// }

// func NewDocComment(text string) ValueElem {
// 	return nil
// }

// newContext returns a new evaluation context.
func newContext(idx *runtime.Runtime) *adt.OpContext {
	if idx == nil {
		return nil
	}
	return eval.NewContext(idx, nil)
}

func debugStr(ctx *adt.OpContext, v adt.Node) string {
	return debug.NodeString(ctx, v, nil)
}

func str(c *adt.OpContext, v adt.Node) string {
	return debugStr(c, v)
}

// eval returns the evaluated value. This may not be the vertex.
//
// Deprecated: use ctx.value
func (v Value) eval(ctx *adt.OpContext) adt.Value {
	if v.v == nil {
		panic("undefined value")
	}
	x := manifest(ctx, v.v)
	return x.Value()
}

// TODO: change from Vertex to Vertex.
func manifest(ctx *adt.OpContext, v *adt.Vertex) *adt.Vertex {
	v.Finalize(ctx)
	return v
}
