// 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 codec converts Go to and from CUE and validates Go values based on
// CUE constraints.
//
// CUE constraints can be used to validate Go types as well as fill out
// missing struct fields that are implied from the constraints and the values
// already defined by the struct value.
package gocodec

import (
	"sync"

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

// Config has no options yet, but is defined for future extensibility.
type Config struct {
}

// A Codec decodes and encodes CUE from and to Go values and validates and
// completes Go values based on CUE templates.
type Codec struct {
	runtime *cue.Runtime
	mutex   sync.RWMutex
}

// New creates a new Codec for the given instance.
//
// It is safe to use the methods of Codec concurrently as long as the given
// Runtime is not used elsewhere while using Codec. However, only the concurrent
// use of Decode, Validate, and Complete is efficient.
func New(r *cue.Runtime, c *Config) *Codec {
	return &Codec{runtime: r}
}

// ExtractType extracts a CUE value from a Go type.
//
// The type represented by x is converted as the underlying type. Specific
// values, such as map or slice elements or field values of structs are ignored.
// If x is of type reflect.Type, the type represented by x is extracted.
//
// Fields of structs can be annoted using additional constrains using the 'cue'
// field tag. The value of the tag is a CUE expression, which may contain
// references to the JSON name of other fields in a struct.
//
//     type Sum struct {
//         A int `cue:"c-b" json:"a,omitempty"`
//         B int `cue:"c-a" json:"b,omitempty"`
//         C int `cue:"a+b" json:"c,omitempty"`
//     }
//
func (c *Codec) ExtractType(x interface{}) (cue.Value, error) {
	// ExtractType cannot introduce new fields on repeated calls. We could
	// consider optimizing the lock usage based on this property.
	c.mutex.Lock()
	defer c.mutex.Unlock()

	return fromGoType(c.runtime, x)
}

// TODO: allow extracting constraints and type info separately?

// Decode converts x to a CUE value.
//
// If x is of type reflect.Value it will convert the value represented by x.
func (c *Codec) Decode(x interface{}) (cue.Value, error) {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	// Depending on the type, can introduce new labels on repeated calls.
	return fromGoValue(c.runtime, x, false)
}

// Encode converts v to a Go value.
func (c *Codec) Encode(v cue.Value, x interface{}) error {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	return v.Decode(x)
}

var defaultCodec = New(&cue.Runtime{}, nil)

// Validate calls Validate on a default Codec for the type of x.
func Validate(x interface{}) error {
	c := defaultCodec
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	r := defaultCodec.runtime
	v, err := fromGoType(r, x)
	if err != nil {
		return err
	}
	w, err := fromGoValue(r, x, false)
	if err != nil {
		return err
	}
	v = v.Unify(w)
	if err := v.Validate(); err != nil {
		return err
	}
	return nil
}

// Validate checks whether x satisfies the constraints defined by v.
//
// The given value must be created using the same Runtime with which c was
// initialized.
func (c *Codec) Validate(v cue.Value, x interface{}) error {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	r := checkAndForkRuntime(c.runtime, v)
	w, err := fromGoValue(r, x, false)
	if err != nil {
		return err
	}
	return w.Unify(v).Err()
}

// Complete sets previously undefined values in x that can be uniquely
// determined form the constraints defined by v if validation passes, or returns
// an error, without modifying anything, otherwise.
//
// Only undefined values are modified. A value is considered undefined if it is
// pointer type and is nil or if it is a field with a zero value that has a json
// tag with the omitempty flag.
//
// The given value must be created using the same Runtime with which c was
// initialized.
//
// 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 *Codec) Complete(v cue.Value, x interface{}) error {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	r := checkAndForkRuntime(c.runtime, v)
	w, err := fromGoValue(r, x, true)
	if err != nil {
		return err
	}

	return w.Unify(v).Decode(x)
}

func fromGoValue(r *cue.Runtime, x interface{}, allowDefault bool) (cue.Value, error) {
	v := internal.FromGoValue(r, x, allowDefault).(cue.Value)
	if err := v.Err(); err != nil {
		return v, err
	}
	return v, nil
}

func fromGoType(r *cue.Runtime, x interface{}) (cue.Value, error) {
	v := internal.FromGoType(r, x).(cue.Value)
	if err := v.Err(); err != nil {
		return v, err
	}
	return v, nil
}

func checkAndForkRuntime(r *cue.Runtime, v cue.Value) *cue.Runtime {
	return internal.CheckAndForkRuntime(r, v).(*cue.Runtime)
}
