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

// TODO:
// - replace converter from YAML to CUE to CUE (schema) to CUE.
// - define OpenAPI definitions als CUE.

import (
	"fmt"
	"path"
	"path/filepath"
	"sort"
	"strings"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
)

const rootDefs = "def"

// A decoder converts JSON schema to CUE.
type decoder struct {
	cfg *Config

	errs    errors.Error
	imports map[string]*ast.Ident

	definitions []ast.Decl
}

// addImport registers
func (d *decoder) addImport(pkg string) *ast.Ident {
	ident, ok := d.imports[pkg]
	if !ok {
		ident = ast.NewIdent(pkg)
		d.imports[pkg] = ident
	}
	return ident
}

func (d *decoder) decode(inst *cue.Instance) *ast.File {
	root := state{decoder: d}
	expr, state := root.schemaState(inst.Value())

	var a []ast.Decl

	filename := d.cfg.ID
	name := filepath.ToSlash(filename)
	if state.id != "" {
		name = strings.Trim(name, "#")
	}
	pkgName := path.Base(name)
	pkgName = pkgName[:len(pkgName)-len(path.Ext(pkgName))]
	pkg := &ast.Package{Name: ast.NewIdent(pkgName)}
	state.doc(pkg)

	a = append(a, pkg)

	var imports []string
	for k := range d.imports {
		imports = append(imports, k)
	}
	sort.Strings(imports)

	if len(imports) > 0 {
		x := &ast.ImportDecl{}
		for _, p := range imports {
			x.Specs = append(x.Specs, ast.NewImport(nil, p))
		}
		a = append(a, x)
	}

	tags := []string{}
	if state.jsonschema != "" {
		tags = append(tags, fmt.Sprintf("schema=%q", state.jsonschema))
	}
	if state.id != "" {
		tags = append(tags, fmt.Sprintf("id=%q", state.id))
	}
	if len(tags) > 0 {
		a = append(a, addTag("Schema", "jsonschema", strings.Join(tags, ",")))
	}

	if state.deprecated {
		a = append(a, addTag("Schema", "deprecated", ""))
	}

	f := &ast.Field{
		Label: ast.NewIdent("Schema"),
		Value: expr,
	}

	f.Token = token.ISA
	a = append(a, f)
	a = append(a, d.definitions...)

	return &ast.File{Decls: a}
}

func (d *decoder) errf(n cue.Value, format string, args ...interface{}) ast.Expr {
	d.warnf(n, format, args...)
	return &ast.BadExpr{From: n.Pos()}
}

func (d *decoder) warnf(n cue.Value, format string, args ...interface{}) {
	d.errs = errors.Append(d.errs, errors.Newf(n.Pos(), format, args...))
}

func (d *decoder) number(n cue.Value) ast.Expr {
	return n.Syntax().(ast.Expr)
}

func (d *decoder) uint(n cue.Value) ast.Expr {
	_, err := n.Uint64()
	if err != nil {
		d.errf(n, "invalid uint")
	}
	return n.Syntax().(ast.Expr)
}

func (d *decoder) bool(n cue.Value) ast.Expr {
	return n.Syntax().(ast.Expr)
}

func (d *decoder) boolValue(n cue.Value) bool {
	x, err := n.Bool()
	if err != nil {
		d.errf(n, "invalid bool")
	}
	return x
}

func (d *decoder) string(n cue.Value) ast.Expr {
	return n.Syntax().(ast.Expr)
}

func (d *decoder) strValue(n cue.Value) (s string, ok bool) {
	s, err := n.String()
	if err != nil {
		d.errf(n, "invalid string")
		return "", false
	}
	return s, true
}

// const draftCutoff = 5

type state struct {
	*decoder

	path []string

	pos cue.Value

	types        []cue.Value
	typeOptional bool
	kind         cue.Kind

	default_    ast.Expr
	examples    []ast.Expr
	title       string
	description string
	deprecated  bool
	jsonschema  string
	id          string

	conjuncts []ast.Expr

	obj         *ast.StructLit
	closeStruct bool
	patterns    []ast.Expr

	list *ast.ListLit
}

// finalize constructs a CUE type from the collected constraints.
func (s *state) finalize() (e ast.Expr) {
	if s.typeOptional || s.kind != 0 {
		if len(s.types) > 1 {
			s.errf(s.pos, "constraints require specific type")
		}
		s.types = nil
	}

	conjuncts := []ast.Expr{}
	disjuncts := []ast.Expr{}
	for _, n := range s.types {
		add := func(e ast.Expr) {
			disjuncts = append(disjuncts, setPos(e, n))
		}
		str, ok := s.strValue(n)
		if !ok {
			s.errf(n, "type value should be a string")
			return
		}
		switch str {
		case "null":
			// TODO: handle OpenAPI restrictions.
			add(ast.NewIdent("null"))
		case "boolean":
			add(ast.NewIdent("bool"))
		case "string":
			add(ast.NewIdent("string"))
		case "number":
			add(ast.NewIdent("number"))
		case "integer":
			add(ast.NewIdent("int"))
		case "array":
			if s.kind&cue.ListKind == 0 {
				add(ast.NewList(&ast.Ellipsis{}))
			}
		case "object":
			add(ast.NewStruct(&ast.Ellipsis{}))
		default:
			s.errf(n, "unknown type %q", n)
		}
	}
	if len(disjuncts) > 0 {
		conjuncts = append(conjuncts, ast.NewBinExpr(token.OR, disjuncts...))
	}

	conjuncts = append(conjuncts, s.conjuncts...)

	if s.obj != nil {
		if !s.closeStruct {
			s.obj.Elts = append(s.obj.Elts, &ast.Ellipsis{})
		}
		conjuncts = append(conjuncts, s.obj)
	}

	if len(conjuncts) == 0 {
		return ast.NewString(fmt.Sprint(s.pos))
	}

	e = ast.NewBinExpr(token.AND, conjuncts...)

	if s.default_ != nil {
		// check conditions where default can be skipped.
		switch x := s.default_.(type) {
		case *ast.ListLit:
			if s.kind == cue.ListKind && len(x.Elts) == 0 {
				return e
			}
		}
		e = ast.NewBinExpr(token.OR, e, &ast.UnaryExpr{Op: token.MUL, X: s.default_})
	}
	return e
}

func (s *state) doc(n ast.Node) {
	// Create documentation.
	doc := strings.TrimSpace(s.title)
	if s.description != "" {
		if doc != "" {
			doc += "\n\n"
		}
		doc += s.description
		doc = strings.TrimSpace(doc)
	}
	if doc != "" {
		ast.SetComments(n, []*ast.CommentGroup{
			internal.NewComment(true, doc),
		})
	}

	// TODO: add examples as well?
}

func (s *state) add(e ast.Expr) {
	s.conjuncts = append(s.conjuncts, e)
}

func (s *state) schema(n cue.Value) ast.Expr {
	expr, _ := s.schemaState(n)
	// TODO: report unused doc.
	return expr
}

func (s *state) schemaState(n cue.Value) (ast.Expr, *state) {
	state := &state{path: s.path, pos: n, decoder: s.decoder}

	if n.Kind() != cue.StructKind {
		return s.errf(n, "schema expects mapping node, found %s", n.Kind()), state
	}

	// do multiple passes over the constraints to ensure they are done in order.
	for pass := 0; pass < 3; pass++ {
		state.processMap(n, func(key string, value cue.Value) {
			// Convert each constraint into a either a value or a functor.
			c := constraintMap[key]
			if c == nil {
				if pass == 0 {
					s.warnf(n, "unsupported constraint %q", key)
				}
				return
			}
			if c.phase == pass {
				c.fn(value, state)
			}
		})
	}

	return state.finalize(), state
}

func (s *state) value(n cue.Value) ast.Expr {
	switch n.Kind() {
	case cue.ListKind:
		a := []ast.Expr{}
		for i, _ := n.List(); i.Next(); {
			a = append(a, s.value(i.Value()))
		}
		return setPos(ast.NewList(a...), n)

	case cue.StructKind:
		a := []ast.Decl{}
		s.processMap(n, func(key string, n cue.Value) {
			a = append(a, &ast.Field{
				Label: ast.NewString(key),
				Value: s.value(n),
			})
		})
		a = append(a, &ast.Ellipsis{})
		return setPos(&ast.StructLit{Elts: a}, n)

	default:
		if !n.IsConcrete() {
			s.errf(n, "invalid non-concerte value")
		}
		return n.Syntax().(ast.Expr)
	}
}

// processMap processes a yaml node, expanding merges.
//
// TODO: in some cases we can translate merges into CUE embeddings.
// This may also prevent exponential blow-up (as may happen when
// converting YAML to JSON).
func (s *state) processMap(n cue.Value, f func(key string, n cue.Value)) {
	saved := s.path
	defer func() { s.path = saved }()

	// TODO: intercept references to allow for optimized performance.
	for i, _ := n.Fields(); i.Next(); {
		key := i.Label()
		s.path = append(saved, key)
		f(key, i.Value())
	}
}

func list(n cue.Value) (a []cue.Value) {
	for i, _ := n.List(); i.Next(); {
		a = append(a, i.Value())
	}
	return a
}

// excludeFields returns a CUE expression that can be used to exclude the
// fields of the given declaration in a label expression. For instance, for
//
//    { foo: 1, bar: int }
//
// it creates
//
//    "^(foo|bar)$"
//
// which can be used in a label expression to define types for all fields but
// those existing:
//
//   [!~"^(foo|bar)$"]: string
//
func excludeFields(decls []ast.Decl) ast.Expr {
	var a []string
	for _, d := range decls {
		f, ok := d.(*ast.Field)
		if !ok {
			continue
		}
		str, _, _ := ast.LabelName(f.Label)
		if str != "" {
			a = append(a, str)
		}
	}
	re := fmt.Sprintf("^(%s)$", strings.Join(a, "|"))
	return &ast.UnaryExpr{Op: token.NMAT, X: ast.NewString(re)}
}

func addTag(field, tag, value string) *ast.Field {
	return &ast.Field{
		Label: ast.NewIdent(field),
		Token: token.ISA,
		Value: ast.NewIdent("_"),
		Attrs: []*ast.Attribute{
			{Text: fmt.Sprintf("@%s(%s)", tag, value)},
		},
	}
}

func setPos(e ast.Expr, v cue.Value) ast.Expr {
	ast.SetPos(e, v.Pos())
	return e
}
