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

import (
	"fmt"
	"math/big"
	"path"
	"regexp"

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

// TODO: skip invalid regexps containing ?! and foes.
// alternatively, fall back to  https://github.com/dlclark/regexp2

type constraint struct {
	key string

	// phase indicates on which pass c constraint should be added. This ensures
	// that constraints are applied in the correct order. For instance, the
	// "required" constraint validates that a listed field is contained in
	// "properties". For this to work, "properties" must be processed before
	// "required" and thus must have a lower phase number than the latter.
	phase int

	// Indicates the draft number in which this constraint is defined.
	draft int
	fn    constraintFunc
}

// A constraintFunc converts a given JSON Schema constraint (specified in n)
// to a CUE constraint recorded in state.
type constraintFunc func(n cue.Value, s *state)

func p0(name string, f constraintFunc) *constraint {
	return &constraint{key: name, fn: f}
}

func p1d(name string, draft int, f constraintFunc) *constraint {
	return &constraint{key: name, phase: 1, draft: draft, fn: f}
}

func p1(name string, f constraintFunc) *constraint {
	return &constraint{key: name, phase: 1, fn: f}
}

func p2(name string, f constraintFunc) *constraint {
	return &constraint{key: name, phase: 2, fn: f}
}

func p3(name string, f constraintFunc) *constraint {
	return &constraint{key: name, phase: 3, fn: f}
}

// TODO:
// writeOnly, readOnly

var constraintMap = map[string]*constraint{}

func init() {
	for _, c := range constraints {
		constraintMap[c.key] = c
	}
}

func addDefinitions(n cue.Value, s *state) {
	if n.Kind() != cue.StructKind {
		s.errf(n, `"definitions" expected an object, found %s`, n.Kind())
	}

	old := s.isSchema
	s.isSchema = true
	defer func() { s.isSchema = old }()

	s.processMap(n, func(key string, n cue.Value) {
		name := key

		var f *ast.Field

		ident := "#" + name
		if ast.IsValidIdent(ident) {
			f = &ast.Field{Value: s.schema(n, label{ident, true})}
			f.Label = ast.NewIdent(ident)
		} else {
			f = &ast.Field{Value: s.schema(n, label{"#", true}, label{name: name})}
			f.Label = ast.NewString(name)
			ident = "#"
			f = &ast.Field{
				Label: ast.NewIdent("#"),
				Value: ast.NewStruct(f),
			}
		}

		ast.SetRelPos(f, token.NewSection)
		s.definitions = append(s.definitions, f)
		s.setField(label{name: ident, isDef: true}, f)
	})
}

var constraints = []*constraint{
	// Meta data.

	p0("$schema", func(n cue.Value, s *state) {
		// Identifies this as a JSON schema and specifies its version.
		// TODO: extract version.
		s.jsonschema, _ = s.strValue(n)
	}),

	p0("$id", func(n cue.Value, s *state) {
		// URL: https://domain.com/schemas/foo.json
		// anchors: #identifier
		//
		// TODO: mark identifiers.

		// Resolution must be relative to parent $id
		// https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2
		u := s.resolveURI(n)
		if u == nil {
			return
		}

		if u.Fragment != "" {
			if s.cfg.Strict {
				s.errf(n, "$id URI may not contain a fragment")
			}
			return
		}
		s.id = u

		obj := s.object(n)

		// TODO: handle the case where this is always defined and we don't want
		// to include the default value.
		obj.Elts = append(obj.Elts, &ast.Attribute{
			Text: fmt.Sprintf("@jsonschema(id=%q)", u)})
	}),

	// Generic constraint

	p1("type", func(n cue.Value, s *state) {
		var types cue.Kind
		set := func(n cue.Value) {
			str, ok := s.strValue(n)
			if !ok {
				s.errf(n, "type value should be a string")
			}
			switch str {
			case "null":
				types |= cue.NullKind
				s.setTypeUsed(n, nullType)
				// TODO: handle OpenAPI restrictions.
			case "boolean":
				types |= cue.BoolKind
				s.setTypeUsed(n, boolType)
			case "string":
				types |= cue.StringKind
				s.setTypeUsed(n, stringType)
			case "number":
				types |= cue.NumberKind
				s.setTypeUsed(n, numType)
			case "integer":
				types |= cue.IntKind
				s.setTypeUsed(n, numType)
				s.add(n, numType, ast.NewIdent("int"))
			case "array":
				types |= cue.ListKind
				s.setTypeUsed(n, arrayType)
			case "object":
				types |= cue.StructKind
				s.setTypeUsed(n, objectType)

			default:
				s.errf(n, "unknown type %q", n)
			}
		}

		switch n.Kind() {
		case cue.StringKind:
			set(n)
		case cue.ListKind:
			for i, _ := n.List(); i.Next(); {
				set(i.Value())
			}
		default:
			s.errf(n, `value of "type" must be a string or list of strings`)
		}

		s.allowedTypes &= types
	}),

	p1("enum", func(n cue.Value, s *state) {
		var a []ast.Expr
		for _, x := range s.listItems("enum", n, true) {
			a = append(a, s.value(x))
		}
		s.all.add(n, ast.NewBinExpr(token.OR, a...))
	}),

	// TODO: only allow for OpenAPI.
	p1("nullable", func(n cue.Value, s *state) {
		null := ast.NewNull()
		setPos(null, n)
		s.nullable = null
	}),

	p1d("const", 6, func(n cue.Value, s *state) {
		s.all.add(n, s.value(n))
	}),

	p1("default", func(n cue.Value, s *state) {
		sc := *s
		s.default_ = sc.value(n)
		// TODO: must validate that the default is subsumed by the normal value,
		// as CUE will otherwise broaden the accepted values with the default.
		s.examples = append(s.examples, s.default_)
	}),

	p1("deprecated", func(n cue.Value, s *state) {
		if s.boolValue(n) {
			s.deprecated = true
		}
	}),

	p1("examples", func(n cue.Value, s *state) {
		if n.Kind() != cue.ListKind {
			s.errf(n, `value of "examples" must be an array, found %v`, n.Kind)
		}
		// TODO: implement examples properly.
		// for _, n := range s.listItems("examples", n, true) {
		// 	if ex := s.value(n); !isAny(ex) {
		// 		s.examples = append(s.examples, ex)
		// 	}
		// }
	}),

	p1("description", func(n cue.Value, s *state) {
		s.description, _ = s.strValue(n)
	}),

	p1("title", func(n cue.Value, s *state) {
		s.title, _ = s.strValue(n)
	}),

	p1d("$comment", 7, func(n cue.Value, s *state) {
	}),

	p1("$defs", addDefinitions),
	p1("definitions", addDefinitions),
	p1("$ref", func(n cue.Value, s *state) {
		s.usedTypes = allTypes

		u := s.resolveURI(n)

		if u.Fragment != "" && !path.IsAbs(u.Fragment) {
			s.addErr(errors.Newf(n.Pos(), "anchors (%s) not supported", u.Fragment))
			// TODO: support anchors
			return
		}

		expr := s.makeCUERef(n, u)

		if expr == nil {
			expr = &ast.BadExpr{From: n.Pos()}
		}

		s.all.add(n, expr)
	}),

	// Combinators

	// TODO: work this out in more detail: oneOf and anyOf below have the same
	// implementation in CUE. The distinction is that for anyOf a result is
	// allowed to be ambiguous at the end, whereas for oneOf a disjunction must
	// be fully resolved. There is currently no easy way to set this distinction
	// in CUE.
	//
	// One could correctly write oneOf like this once 'not' is implemented:
	//
	//   oneOf(a, b, c) :-
	//      anyOf(
	//         allOf(a, not(b), not(c)),
	//         allOf(not(a), b, not(c)),
	//         allOf(not(a), not(b), c),
	//   ))
	//
	// This is not necessary if the values are mutually exclusive/ have a
	// discriminator.

	p2("allOf", func(n cue.Value, s *state) {
		var a []ast.Expr
		for _, v := range s.listItems("allOf", n, false) {
			x, sub := s.schemaState(v, s.allowedTypes, nil, true)
			s.allowedTypes &= sub.allowedTypes
			s.usedTypes |= sub.usedTypes
			if sub.hasConstraints() {
				a = append(a, x)
			}
		}
		if len(a) > 0 {
			s.all.add(n, ast.NewBinExpr(token.AND, a...))
		}
	}),

	p2("anyOf", func(n cue.Value, s *state) {
		var types cue.Kind
		var a []ast.Expr
		for _, v := range s.listItems("anyOf", n, false) {
			x, sub := s.schemaState(v, s.allowedTypes, nil, true)
			types |= sub.allowedTypes
			a = append(a, x)
		}
		s.allowedTypes &= types
		if len(a) > 0 {
			s.all.add(n, ast.NewBinExpr(token.OR, a...))
		}
	}),

	p2("oneOf", func(n cue.Value, s *state) {
		var types cue.Kind
		var a []ast.Expr
		hasSome := false
		for _, v := range s.listItems("oneOf", n, false) {
			x, sub := s.schemaState(v, s.allowedTypes, nil, true)
			types |= sub.allowedTypes

			// TODO: make more finegrained by making it two pass.
			if sub.hasConstraints() {
				hasSome = true
			}

			if !isAny(x) {
				a = append(a, x)
			}
		}
		s.allowedTypes &= types
		if len(a) > 0 && hasSome {
			s.usedTypes = allTypes
			s.all.add(n, ast.NewBinExpr(token.OR, a...))
		}

		// TODO: oneOf({a:x}, {b:y}, ..., not(anyOf({a:x}, {b:y}, ...))),
		// can be translated to {} | {a:x}, {b:y}, ...
	}),

	// String constraints

	p1("pattern", func(n cue.Value, s *state) {
		str, _ := n.String()
		if _, err := regexp.Compile(str); err != nil {
			if s.cfg.Strict {
				s.errf(n, "unsupported regexp: %v", err)
			}
			return
		}
		s.usedTypes |= cue.StringKind
		s.add(n, stringType, &ast.UnaryExpr{Op: token.MAT, X: s.string(n)})
	}),

	p1("minLength", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StringKind
		min := s.number(n)
		strings := s.addImport(n, "strings")
		s.add(n, stringType, ast.NewCall(ast.NewSel(strings, "MinRunes"), min))
	}),

	p1("maxLength", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StringKind
		max := s.number(n)
		strings := s.addImport(n, "strings")
		s.add(n, stringType, ast.NewCall(ast.NewSel(strings, "MaxRunes"), max))
	}),

	p1d("contentMediaType", 7, func(n cue.Value, s *state) {
		// TODO: only mark as used if it generates something.
		// s.usedTypes |= cue.StringKind
	}),

	p1d("contentEncoding", 7, func(n cue.Value, s *state) {
		// TODO: only mark as used if it generates something.
		// s.usedTypes |= cue.StringKind
		// 7bit, 8bit, binary, quoted-printable and base64.
		// RFC 2054, part 6.1.
		// https://tools.ietf.org/html/rfc2045
		// TODO: at least handle bytes.
	}),

	// Number constraints

	p1("minimum", func(n cue.Value, s *state) {
		s.usedTypes |= cue.NumberKind
		s.add(n, numType, &ast.UnaryExpr{Op: token.GEQ, X: s.number(n)})
	}),

	p1("exclusiveMinimum", func(n cue.Value, s *state) {
		// TODO: should we support Draft 4 booleans?
		s.usedTypes |= cue.NumberKind
		s.add(n, numType, &ast.UnaryExpr{Op: token.GTR, X: s.number(n)})
	}),

	p1("maximum", func(n cue.Value, s *state) {
		s.usedTypes |= cue.NumberKind
		s.add(n, numType, &ast.UnaryExpr{Op: token.LEQ, X: s.number(n)})
	}),

	p1("exclusiveMaximum", func(n cue.Value, s *state) {
		// TODO: should we support Draft 4 booleans?
		s.usedTypes |= cue.NumberKind
		s.add(n, numType, &ast.UnaryExpr{Op: token.LSS, X: s.number(n)})
	}),

	p1("multipleOf", func(n cue.Value, s *state) {
		s.usedTypes |= cue.NumberKind
		multiple := s.number(n)
		var x big.Int
		_, _ = n.MantExp(&x)
		if x.Cmp(big.NewInt(0)) != 1 {
			s.errf(n, `"multipleOf" value must be < 0; found %s`, n)
		}
		math := s.addImport(n, "math")
		s.add(n, numType, ast.NewCall(ast.NewSel(math, "MultipleOf"), multiple))
	}),

	// Object constraints

	p1("properties", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StructKind
		obj := s.object(n)

		if n.Kind() != cue.StructKind {
			s.errf(n, `"properties" expected an object, found %v`, n.Kind)
		}

		s.processMap(n, func(key string, n cue.Value) {
			// property?: value
			name := ast.NewString(key)
			expr, state := s.schemaState(n, allTypes, []label{{name: key}}, false)
			f := &ast.Field{Label: name, Value: expr}
			state.doc(f)
			f.Optional = token.Blank.Pos()
			if len(obj.Elts) > 0 && len(f.Comments()) > 0 {
				// TODO: change formatter such that either a a NewSection on the
				// field or doc comment will cause a new section.
				ast.SetRelPos(f.Comments()[0], token.NewSection)
			}
			if state.deprecated {
				switch expr.(type) {
				case *ast.StructLit:
					obj.Elts = append(obj.Elts, addTag(name, "deprecated", ""))
				default:
					f.Attrs = append(f.Attrs, internal.NewAttr("deprecated", ""))
				}
			}
			obj.Elts = append(obj.Elts, f)
			s.setField(label{name: key}, f)
		})
	}),

	p2("required", func(n cue.Value, s *state) {
		if n.Kind() != cue.ListKind {
			s.errf(n, `value of "required" must be list of strings, found %v`, n.Kind)
			return
		}

		s.usedTypes |= cue.StructKind

		// TODO: detect that properties is defined somewhere.
		// s.errf(n, `"required" without a "properties" field`)
		obj := s.object(n)

		// Create field map
		fields := map[string]*ast.Field{}
		for _, d := range obj.Elts {
			f, ok := d.(*ast.Field)
			if !ok {
				continue // Could be embedding? See cirrus.json
			}
			str, _, err := ast.LabelName(f.Label)
			if err == nil {
				fields[str] = f
			}
		}

		for _, n := range s.listItems("required", n, true) {
			str, ok := s.strValue(n)
			f := fields[str]
			if f == nil && ok {
				f := &ast.Field{
					Label: ast.NewString(str),
					Value: ast.NewIdent("_"),
				}
				fields[str] = f
				obj.Elts = append(obj.Elts, f)
				continue
			}
			if f.Optional == token.NoPos {
				s.errf(n, "duplicate required field %q", str)
			}
			f.Optional = token.NoPos
		}
	}),

	p1d("propertyNames", 6, func(n cue.Value, s *state) {
		// [=~pattern]: _
		if names, _ := s.schemaState(n, cue.StringKind, nil, false); !isAny(names) {
			s.usedTypes |= cue.StructKind
			x := ast.NewStruct(ast.NewList(names), ast.NewIdent("_"))
			s.add(n, objectType, x)
		}
	}),

	// TODO: reenable when we have proper non-monotonic contraint validation.
	// p1("minProperties", func(n cue.Value, s *state) {
	// 	s.usedTypes |= cue.StructKind

	// 	pkg := s.addImport(n, "struct")
	// 	s.addConjunct(n, ast.NewCall(ast.NewSel(pkg, "MinFields"), s.uint(n)))
	// }),

	p1("maxProperties", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StructKind

		pkg := s.addImport(n, "struct")
		x := ast.NewCall(ast.NewSel(pkg, "MaxFields"), s.uint(n))
		s.add(n, objectType, x)
	}),

	p1("dependencies", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StructKind

		// Schema and property dependencies.
		// TODO: the easiest implementation is with comprehensions.
		// The nicer implementation is with disjunctions. This has to be done
		// at the very end, replacing properties.
		/*
			*{ property?: _|_ } | {
				property: _
				schema
			}
		*/
	}),

	p2("patternProperties", func(n cue.Value, s *state) {
		s.usedTypes |= cue.StructKind
		if n.Kind() != cue.StructKind {
			s.errf(n, `value of "patternProperties" must be an an object, found %v`, n.Kind)
		}
		obj := s.object(n)
		existing := excludeFields(s.obj.Elts)
		s.processMap(n, func(key string, n cue.Value) {
			// [!~(properties) & pattern]: schema
			s.patterns = append(s.patterns,
				&ast.UnaryExpr{Op: token.NMAT, X: ast.NewString(key)})
			f := internal.EmbedStruct(ast.NewStruct(&ast.Field{
				Label: ast.NewList(ast.NewBinExpr(token.AND,
					&ast.UnaryExpr{Op: token.MAT, X: ast.NewString(key)},
					existing)),
				Value: s.schema(n),
			}))
			ast.SetRelPos(f, token.NewSection)
			obj.Elts = append(obj.Elts, f)
		})
	}),

	p3("additionalProperties", func(n cue.Value, s *state) {
		switch n.Kind() {
		case cue.BoolKind:
			s.closeStruct = !s.boolValue(n)
			if !s.closeStruct {
				s.usedTypes |= cue.StructKind
			}

		case cue.StructKind:
			s.usedTypes |= cue.StructKind
			s.closeStruct = true
			obj := s.object(n)
			if len(obj.Elts) == 0 {
				obj.Elts = append(obj.Elts, &ast.Field{
					Label: ast.NewList(ast.NewIdent("string")),
					Value: s.schema(n),
				})
				return
			}
			// [!~(properties|patternProperties)]: schema
			existing := append(s.patterns, excludeFields(obj.Elts))
			f := internal.EmbedStruct(ast.NewStruct(&ast.Field{
				Label: ast.NewList(ast.NewBinExpr(token.AND, existing...)),
				Value: s.schema(n),
			}))
			obj.Elts = append(obj.Elts, f)

		default:
			s.errf(n, `value of "additionalProperties" must be an object or boolean`)
		}
	}),

	// Array constraints.

	p1("items", func(n cue.Value, s *state) {
		s.usedTypes |= cue.ListKind
		switch n.Kind() {
		case cue.StructKind:
			elem := s.schema(n)
			ast.SetRelPos(elem, token.NoRelPos)
			s.add(n, arrayType, ast.NewList(&ast.Ellipsis{Type: elem}))

		case cue.ListKind:
			var a []ast.Expr
			for _, n := range s.listItems("items", n, true) {
				v := s.schema(n) // TODO: label with number literal.
				ast.SetRelPos(v, token.NoRelPos)
				a = append(a, v)
			}
			s.list = ast.NewList(a...)
			s.add(n, arrayType, s.list)

		default:
			s.errf(n, `value of "items" must be an object or array`)
		}
	}),

	p1("additionalItems", func(n cue.Value, s *state) {
		switch n.Kind() {
		case cue.BoolKind:
			// TODO: support

		case cue.StructKind:
			if s.list != nil {
				s.usedTypes |= cue.ListKind
				elem := s.schema(n)
				s.list.Elts = append(s.list.Elts, &ast.Ellipsis{Type: elem})
			}

		default:
			s.errf(n, `value of "additionalItems" must be an object or boolean`)
		}
	}),

	p1("contains", func(n cue.Value, s *state) {
		s.usedTypes |= cue.ListKind
		list := s.addImport(n, "list")
		// TODO: Passing non-concrete values is not yet supported in CUE.
		if x := s.schema(n); !isAny(x) {
			x := ast.NewCall(ast.NewSel(list, "Contains"), clearPos(x))
			s.add(n, arrayType, x)
		}
	}),

	// TODO: min/maxContains

	p1("minItems", func(n cue.Value, s *state) {
		s.usedTypes |= cue.ListKind
		a := []ast.Expr{}
		p, err := n.Uint64()
		if err != nil {
			s.errf(n, "invalid uint")
		}
		for ; p > 0; p-- {
			a = append(a, ast.NewIdent("_"))
		}
		s.add(n, arrayType, ast.NewList(append(a, &ast.Ellipsis{})...))

		// TODO: use this once constraint resolution is properly implemented.
		// list := s.addImport(n, "list")
		// s.addConjunct(n, ast.NewCall(ast.NewSel(list, "MinItems"), clearPos(s.uint(n))))
	}),

	p1("maxItems", func(n cue.Value, s *state) {
		s.usedTypes |= cue.ListKind
		list := s.addImport(n, "list")
		x := ast.NewCall(ast.NewSel(list, "MaxItems"), clearPos(s.uint(n)))
		s.add(n, arrayType, x)

	}),

	p1("uniqueItems", func(n cue.Value, s *state) {
		s.usedTypes |= cue.ListKind
		if s.boolValue(n) {
			list := s.addImport(n, "list")
			s.add(n, arrayType, ast.NewCall(ast.NewSel(list, "UniqueItems")))
		}
	}),
}

func clearPos(e ast.Expr) ast.Expr {
	ast.SetRelPos(e, token.NoRelPos)
	return e
}
