// Copyright 2019 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 cuego

import (
	"fmt"
	"reflect"
	"sync"

	"cuelang.org/go/cue/parser"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/legacy/cue"
)

// DefaultContext is the shared context used with top-level functions.
var DefaultContext = &Context{}

// MustConstrain is like Constrain, but panics if there is an error.
func MustConstrain(x interface{}, constraints string) {
	if err := Constrain(x, constraints); err != nil {
		panic(err)
	}
}

// Constrain associates the given CUE constraints with the type of x or
// reports an error if the constraints are invalid or not compatible with x.
//
// Constrain works across package boundaries and is typically called in the
// package defining the type. Use a Context to apply constraints locally.
func Constrain(x interface{}, constraints string) error {
	return DefaultContext.Constrain(x, constraints)
}

// Validate is a wrapper for Validate called on the global context.
func Validate(x interface{}) error {
	return DefaultContext.Validate(x)
}

// Complete sets previously undefined values in x that can be uniquely
// determined form the constraints defined on the type of x such that validation
// passes, or returns an error, without modifying anything, if this is not
// possible.
//
// Complete does a JSON round trip. This means that data not preserved in such a
// round trip, such as the location name of a time.Time, is lost after a
// successful update.
func Complete(x interface{}) error {
	return DefaultContext.Complete(x)
}

// A Context holds type constraints that are only applied within a given
// context.
// Global constraints that are defined at the time a constraint is
// created are applied as well.
type Context struct {
	typeCache sync.Map // map[reflect.Type]cue.Value
}

// Validate checks whether x validates against the registered constraints for
// the type of x.
//
// Constraints for x can be defined as field tags or through the Register
// function.
func (c *Context) Validate(x interface{}) error {
	a := c.load(x)
	v, err := fromGoValue(x, false)
	if err != nil {
		return err
	}
	v = a.Unify(v)
	if err := v.Validate(); err != nil {
		return err
	}
	// TODO: validate all values are concrete. (original value subsumes result?)
	return nil
}

// Complete sets previously undefined values in x that can be uniquely
// determined form the constraints defined on the type of x such that validation
// passes, or returns an error, without modifying anything, if this is not
// possible.
//
// A value is considered undefined if it is pointer type and is nil or if it
// is a field with a zero value and a json tag with the omitempty tag.
// Complete does a JSON round trip. This means that data not preserved in such a
// round trip, such as the location name of a time.Time, is lost after a
// successful update.
func (c *Context) Complete(x interface{}) error {
	a := c.load(x)
	v, err := fromGoValue(x, true)
	if err != nil {
		return err
	}
	v = a.Unify(v)
	if err := v.Validate(); err != nil {
		return err
	}
	return v.Decode(x)
}

func (c *Context) load(x interface{}) cue.Value {
	t := reflect.TypeOf(x)
	if value, ok := c.typeCache.Load(t); ok {
		return value.(cue.Value)
	}

	// fromGoType should prevent the work is done no more than once, but even
	// if it is, there is no harm done.
	v := fromGoType(x)
	c.typeCache.Store(t, v)
	return v
}

// TODO: should we require that Constrain be defined on exported,
// named types types only?

// Constrain associates the given CUE constraints with the type of x or reports
// an error if the constraints are invalid or not compatible with x.
func (c *Context) Constrain(x interface{}, constraints string) error {
	c.load(x) // Ensure fromGoType is called outside of lock.

	mutex.Lock()
	defer mutex.Unlock()

	expr, err := parser.ParseExpr(fmt.Sprintf("<%T>", x), constraints)
	if err != nil {
		return err
	}

	v := instance.Eval(expr)
	if v.Err() != nil {
		return err
	}

	typ := c.load(x)
	v = typ.Unify(v)

	if err := v.Validate(); err != nil {
		return err
	}

	t := reflect.TypeOf(x)
	c.typeCache.Store(t, v)
	return nil
}

var (
	mutex    sync.Mutex
	instance *cue.Instance
	runtime  = &cue.Runtime{}
)

func init() {
	var err error
	instance, err = runtime.Compile("<cuego>", "{}")
	if err != nil {
		panic(err)
	}
}

// fromGoValue converts a Go value to CUE
func fromGoValue(x interface{}, nilIsNull bool) (v cue.Value, err error) {
	// TODO: remove the need to have a lock here. We could use a new index (new
	// Instance) here as any previously unrecognized field can never match an
	// existing one and can only be merged.
	mutex.Lock()
	v = internal.FromGoValue(runtime, x, nilIsNull).(cue.Value)
	mutex.Unlock()
	if err := v.Err(); err != nil {
		return v, err
	}
	return v, nil

	// // This should be equivalent to the following:
	// b, err := json.Marshal(x)
	// if err != nil {
	// 	return v, err
	// }
	// expr, err := parser.ParseExpr(fset, "", b)
	// if err != nil {
	// 	return v, err
	// }
	// mutex.Lock()
	// v = instance.Eval(expr)
	// mutex.Unlock()
	// return v, nil

}

func fromGoType(x interface{}) cue.Value {
	// TODO: remove the need to have a lock here. We could use a new index (new
	// Instance) here as any previously unrecognized field can never match an
	// existing one and can only be merged.
	mutex.Lock()
	v := internal.FromGoType(runtime, x).(cue.Value)
	mutex.Unlock()
	return v
}
