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

import (
	"strings"

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

// Extract converts OpenAPI definitions to an equivalent CUE representation.
//
// It currently only converts entries in #/components/schema and extracts some
// meta data.
func Extract(data *cue.Instance, c *Config) (*ast.File, error) {
	// TODO: find a good OpenAPI validator. Both go-openapi and kin-openapi
	// seem outdated. The k8s one might be good, but avoid pulling in massive
	// amounts of dependencies.

	f := &ast.File{}
	add := func(d ast.Decl) {
		if d != nil {
			f.Decls = append(f.Decls, d)
		}
	}

	js, err := jsonschema.Extract(data, &jsonschema.Config{
		Root: oapiSchemas,
		Map:  openAPIMapping,
	})
	if err != nil {
		return nil, err
	}

	v := data.Value()

	doc, _ := v.Lookup("info", "title").String() // Required
	if s, _ := v.Lookup("info", "description").String(); s != "" {
		doc += "\n\n" + s
	}
	cg := internal.NewComment(true, doc)

	if c.PkgName != "" {
		p := &ast.Package{Name: ast.NewIdent(c.PkgName)}
		p.AddComment(cg)
		add(p)
	} else {
		add(cg)
	}

	i := 0
	for ; i < len(js.Decls); i++ {
		switch x := js.Decls[i].(type) {
		case *ast.Package:
			return nil, errors.Newf(x.Pos(), "unexpected package %q", x.Name.Name)

		case *ast.ImportDecl, *ast.CommentGroup:
			add(x)
			continue
		}
		break
	}

	// TODO: allow attributes before imports? Would be easier.

	// TODO: do we want to store the OpenAPI version?
	// if version, _ := v.Lookup("openapi").String(); version != "" {
	// 	add(internal.NewAttr("openapi", "version="+ version))
	// }

	if info := v.Lookup("info"); info.Exists() {
		decls := []interface{}{}
		if st, ok := info.Syntax().(*ast.StructLit); ok {
			// Remove title.
			for _, d := range st.Elts {
				if f, ok := d.(*ast.Field); ok {
					switch name, _, _ := ast.LabelName(f.Label); name {
					case "title", "version":
						// title: *"title" | string
						decls = append(decls, &ast.Field{
							Label: f.Label,
							Value: ast.NewBinExpr(token.OR,
								&ast.UnaryExpr{Op: token.MUL, X: f.Value},
								ast.NewIdent("string")),
						})
						continue
					}
				}
				decls = append(decls, d)
			}
			add(&ast.Field{
				Label: ast.NewIdent("info"),
				Value: ast.NewStruct(decls...),
			})
		}
	}

	if i < len(js.Decls) {
		ast.SetRelPos(js.Decls[i], token.NewSection)
		f.Decls = append(f.Decls, js.Decls[i:]...)
	}

	return f, nil
}

const oapiSchemas = "#/components/schemas/"

// rootDefs is the fallback for schemas that are not valid identifiers.
// TODO: find something more principled.
const rootDefs = "#SchemaMap"

func openAPIMapping(pos token.Pos, a []string) ([]ast.Label, error) {
	if len(a) != 3 || a[0] != "components" || a[1] != "schemas" {
		return nil, errors.Newf(pos,
			`openapi: reference must be of the form %q; found "#/%s"`,
			oapiSchemas, strings.Join(a, "/"))
	}
	name := a[2]
	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
}
