// Copyright 2020 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 (
	"net/url"
	"path"
	"strconv"
	"strings"

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

func (d *decoder) parseRef(p token.Pos, str string) []string {
	u, err := url.Parse(str)
	if err != nil {
		d.addErr(errors.Newf(p, "invalid JSON reference: %s", err))
		return nil
	}

	if u.Host != "" || u.Path != "" {
		d.addErr(errors.Newf(p, "external references (%s) not supported", str))
		// TODO: handle
		//    host:
		//      If the host corresponds to a package known to cue,
		//      load it from there. It would prefer schema converted to
		//      CUE, although we could consider loading raw JSON schema
		//      if present.
		//      If not present, advise the user to run cue get.
		//    path:
		//      Look up on file system or relatively to authority location.
		return nil
	}

	if !path.IsAbs(u.Fragment) {
		d.addErr(errors.Newf(p, "anchors (%s) not supported", u.Fragment))
		// TODO: support anchors
		return nil
	}

	// NOTE: Go bug?: url.URL has no raw representation of the fragment. This
	// means that %2F gets translated to `/` before it can be split. This, in
	// turn, means that field names cannot have a `/` as name.

	return splitFragment(u)
}

// resolveURI parses a URI from n and resolves it in the current context.
// To resolve it in the current context, it looks for the closest URI from
// an $id in the parent scopes and the uses the URI resolution to get the
// new URI.
//
// This method is used to resolve any URI, including those from $id and $ref.
func (s *state) resolveURI(n cue.Value) *url.URL {
	str, ok := s.strValue(n)
	if !ok {
		return nil
	}

	u, err := url.Parse(str)
	if err != nil {
		s.addErr(errors.Newf(n.Pos(), "invalid JSON reference: %s", err))
		return nil
	}

	for {
		if s.id != nil {
			u = s.id.ResolveReference(u)
			break
		}
		if s.up == nil {
			break
		}
		s = s.up
	}

	return u
}

const topSchema = "_schema"

// makeCUERef converts a URI into a CUE reference for the current location.
// The returned identifier (or first expression in a selection chain), is
// hardwired to point to the resolved value. This will allow astutil.Sanitize
// to automatically unshadow any shadowed variables.
func (s *state) makeCUERef(n cue.Value, u *url.URL) ast.Expr {
	a := splitFragment(u)

	switch fn := s.cfg.Map; {
	case fn != nil:
		// TODO: This block is only used in case s.cfg.Map is set, which is
		// currently only used for OpenAPI. Handling should be brought more in
		// line with JSON schema.
		a, err := fn(n.Pos(), a)
		if err != nil {
			s.addErr(errors.Newf(n.Pos(), "invalid reference %q: %v", u, err))
			return nil
		}
		if len(a) == 0 {
			// TODO: should we allow inserting at root level?
			s.addErr(errors.Newf(n.Pos(),
				"invalid empty reference returned by map for %q", u))
			return nil
		}
		sel, ok := a[0].(ast.Expr)
		if !ok {
			sel = &ast.BadExpr{}
		}
		for _, l := range a[1:] {
			switch x := l.(type) {
			case *ast.Ident:
				sel = &ast.SelectorExpr{X: sel, Sel: x}

			case *ast.BasicLit:
				sel = &ast.IndexExpr{X: sel, Index: x}
			}
		}
		return sel
	}

	var ident *ast.Ident

	for ; ; s = s.up {
		if s.up == nil {
			switch {
			case u.Host == "" && u.Path == "",
				s.id != nil && s.id.Host == u.Host && s.id.Path == u.Path:
				if len(a) == 0 {
					// refers to the top of the file. We will allow this by
					// creating a helper schema as such:
					//   _schema: {...}
					//   _schema
					// This is created at the finalization stage if
					// hasSelfReference is set.
					s.hasSelfReference = true

					ident = ast.NewIdent(topSchema)
					ident.Node = s.obj
					return ident
				}

				ident, a = s.getNextIdent(n, a)

			case u.Host != "":
				// Reference not found within scope. Create an import reference.

				// TODO: allow the configuration to specify a map from
				// URI domain+paths to CUE packages.

				// TODO: currently only $ids that are in scope can be
				// referenced. We could consider doing an extra pass to record
				// all '$id's in a file to be able to link to them even if they
				// are not in scope.
				p := u.Path

				base := path.Base(p)
				if !ast.IsValidIdent(base) {
					if strings.HasSuffix(base, ".json") {
						base = base[:len(base)-len(".json")]
					}
					if !ast.IsValidIdent(base) {
						// Find something more clever to do there. For now just
						// pick "schema" as the package name.
						base = "schema"
					}
					p += ":" + base
				}

				ident = ast.NewIdent(base)
				ident.Node = &ast.ImportSpec{Path: ast.NewString(u.Host + p)}

			default:
				// Just a path, not sure what that means.
				s.errf(n, "unknown domain for reference %q", u)
				return nil
			}
			break
		}

		if s.id == nil {
			continue
		}

		if s.id.Host == u.Host && s.id.Path == u.Path {
			if len(a) == 0 {
				if len(s.idRef) == 0 {
					// This is a reference to either root or a schema for which
					// we do not yet support references. See Issue #386.
					if s.up.up != nil {
						s.errf(n, "cannot refer to internal schema %q", u)
						return nil
					}

					// This is referring to the root scope. There is a dummy
					// state above the root state that we need to update.
					s = s.up

					// refers to the top of the file. We will allow this by
					// creating a helper schema as such:
					//   _schema: {...}
					//   _schema
					// This is created at the finalization stage if
					// hasSelfReference is set.
					s.hasSelfReference = true
					ident = ast.NewIdent(topSchema)
					ident.Node = s.obj
					return ident
				}

				x := s.idRef[0]
				if !x.isDef && !ast.IsValidIdent(x.name) {
					s.errf(n, "referring to field %q not supported", x.name)
					return nil
				}
				e := ast.NewIdent(x.name)
				if len(s.idRef) == 1 {
					return e
				}
				return newSel(e, s.idRef[1])
			}
			ident, a = s.getNextIdent(n, a)
			ident.Node = s.obj
			break
		}
	}

	return s.newSel(ident, n, a)
}

// getNextSelector translates a JSON Reference path into a CUE path by consuming
// the first path elements and returning the corresponding CUE label.
func (s *state) getNextSelector(v cue.Value, a []string) (l label, tail []string) {
	switch elem := a[0]; elem {
	case "$defs", "definitions":
		if len(a) == 1 {
			s.errf(v, "cannot refer to %s section: must refer to one of its elements", a[0])
			return label{}, nil
		}

		if name := "#" + a[1]; ast.IsValidIdent(name) {
			return label{name, true}, a[2:]
		}

		return label{"#", true}, a[1:]

	case "properties":
		if len(a) == 1 {
			s.errf(v, "cannot refer to %s section: must refer to one of its elements", a[0])
			return label{}, nil
		}

		return label{a[1], false}, a[2:]

	default:
		return label{elem, false}, a[1:]

	case "additionalProperties",
		"patternProperties",
		"items",
		"additionalItems":
		// TODO: as a temporary workaround, include the schema verbatim.
		// TODO: provide definitions for these in CUE.
		s.errf(v, "referring to field %q not yet supported", elem)

		// Other known fields cannot be supported.
		return label{}, nil
	}
}

// newSel converts a JSON Reference path and initial CUE identifier to
// a CUE selection path.
func (s *state) newSel(e ast.Expr, v cue.Value, a []string) ast.Expr {
	for len(a) > 0 {
		var label label
		label, a = s.getNextSelector(v, a)
		e = newSel(e, label)
	}
	return e
}

// newSel converts label to a CUE index and creates an expression to index
// into e.
func newSel(e ast.Expr, label label) ast.Expr {
	if label.isDef {
		return ast.NewSel(e, label.name)

	}
	if ast.IsValidIdent(label.name) && !internal.IsDefOrHidden(label.name) {
		return ast.NewSel(e, label.name)
	}
	return &ast.IndexExpr{X: e, Index: ast.NewString(label.name)}
}

func (s *state) setField(lab label, f *ast.Field) {
	x := s.getRef(lab)
	x.field = f
	s.setRef(lab, x)
	x = s.getRef(lab)
}

func (s *state) getRef(lab label) refs {
	if s.fieldRefs == nil {
		s.fieldRefs = make(map[label]refs)
	}
	x, ok := s.fieldRefs[lab]
	if !ok {
		if lab.isDef ||
			(ast.IsValidIdent(lab.name) && !internal.IsDefOrHidden(lab.name)) {
			x.ident = lab.name
		} else {
			x.ident = "_X" + strconv.Itoa(s.decoder.numID)
			s.decoder.numID++
		}
		s.fieldRefs[lab] = x
	}
	return x
}

func (s *state) setRef(lab label, r refs) {
	s.fieldRefs[lab] = r
}

// getNextIdent gets the first CUE reference from a JSON Reference path and
// converts it to a CUE identifier.
func (s *state) getNextIdent(v cue.Value, a []string) (resolved *ast.Ident, tail []string) {
	lab, a := s.getNextSelector(v, a)

	x := s.getRef(lab)
	ident := ast.NewIdent(x.ident)
	x.refs = append(x.refs, ident)
	s.setRef(lab, x)

	return ident, a
}

// linkReferences resolves identifiers to relevant nodes. This allows
// astutil.Sanitize to unshadow nodes if necessary.
func (s *state) linkReferences() {
	for _, r := range s.fieldRefs {
		if r.field == nil {
			// TODO: improve error message.
			s.errf(cue.Value{}, "reference to non-existing value %q", r.ident)
			continue
		}

		// link resembles the link value. See astutil.Resolve.
		var link ast.Node

		ident, ok := r.field.Label.(*ast.Ident)
		if ok && ident.Name == r.ident {
			link = r.field.Value
		} else if len(r.refs) > 0 {
			r.field.Label = &ast.Alias{
				Ident: ast.NewIdent(r.ident),
				Expr:  r.field.Label.(ast.Expr),
			}
			link = r.field
		}

		for _, i := range r.refs {
			i.Node = link
		}
	}
}

// splitFragment splits the fragment part of a URI into path components. The
// result may be an empty slice.
//
// TODO: this requires RawFragment introduced in go1.15 to function properly.
// As for now, CUE still uses go1.12.
func splitFragment(u *url.URL) []string {
	if u.Fragment == "" {
		return nil
	}
	s := strings.TrimRight(u.Fragment[1:], "/")
	if s == "" {
		return nil
	}
	return strings.Split(s, "/")
}

func (d *decoder) mapRef(p token.Pos, str string, ref []string) []ast.Label {
	fn := d.cfg.Map
	if fn == nil {
		fn = jsonSchemaRef
	}
	a, err := fn(p, ref)
	if err != nil {
		if str == "" {
			str = "#/" + strings.Join(ref, "/")
		}
		d.addErr(errors.Newf(p, "invalid reference %q: %v", str, err))
		return nil
	}
	if len(a) == 0 {
		// TODO: should we allow inserting at root level?
		if str == "" {
			str = "#/" + strings.Join(ref, "/")
		}
		d.addErr(errors.Newf(p,
			"invalid empty reference returned by map for %q", str))
		return nil
	}
	return a
}

func jsonSchemaRef(p token.Pos, a []string) ([]ast.Label, error) {
	// TODO: technically, references could reference a
	// non-definition. We disallow this case for the standard
	// JSON Schema interpretation. We could detect cases that
	// are not definitions and then resolve those as literal
	// values.
	if len(a) != 2 || (a[0] != "definitions" && a[0] != "$defs") {
		return nil, errors.Newf(p,
			// Don't mention the ability to use $defs, as this definition seems
			// to already have been withdrawn from the JSON Schema spec.
			"$ref must be of the form #/definitions/...")
	}
	name := a[1]
	if ast.IsValidIdent(name) &&
		name != rootDefs[1:] &&
		!internal.IsDefOrHidden(name) {
		return []ast.Label{ast.NewIdent("#" + name)}, nil
	}
	return []ast.Label{ast.NewIdent(rootDefs), ast.NewString(name)}, nil
}
