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

import (
	"encoding/json"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	cuejson "cuelang.org/go/encoding/json"
)

// A Config defines options for converting CUE to and from OpenAPI.
type Config struct {
	// Info specifies the info section of the OpenAPI document. To be a valid
	// OpenAPI document, it must include at least the title and version fields.
	// Info may be a *ast.StructLit or any type that marshals to JSON.
	Info interface{}

	// ReferenceFunc allows users to specify an alternative representation
	// for references. An empty string tells the generator to expand the type
	// in place and, if applicable, not generate a schema for that entity.
	ReferenceFunc func(inst *cue.Instance, path []string) string

	// DescriptionFunc allows rewriting a description associated with a certain
	// field. A typical implementation compiles the description from the
	// comments obtains from the Doc method. No description field is added if
	// the empty string is returned.
	DescriptionFunc func(v cue.Value) string

	// SelfContained causes all non-expanded external references to be included
	// in this document.
	SelfContained bool

	// FieldFilter defines a regular expression of all fields to omit from the
	// output. It is only allowed to filter fields that add additional
	// constraints. Fields that indicate basic types cannot be removed. It is
	// an error for such fields to be excluded by this filter.
	// Fields are qualified by their Object type. For instance, the
	// minimum field of the schema object is qualified as Schema/minimum.
	FieldFilter string

	// ExpandReferences replaces references with actual objects when generating
	// OpenAPI Schema. It is an error for an CUE value to refer to itself
	// if this option is used.
	ExpandReferences bool
}

type Generator = Config

// Gen generates the set OpenAPI schema for all top-level types of the
// given instance.
func Gen(inst *cue.Instance, c *Config) ([]byte, error) {
	if c == nil {
		c = defaultConfig
	}
	all, err := c.All(inst)
	if err != nil {
		return nil, err
	}
	return json.Marshal(all)
}

// Generate generates the set of OpenAPI schema for all top-level types of the
// given instance.
//
// Note: only a limited number of top-level types are supported so far.
func Generate(inst *cue.Instance, c *Config) (*ast.File, error) {
	all, err := schemas(c, inst)
	if err != nil {
		return nil, err
	}
	top, err := c.compose(all)
	if err != nil {
		return nil, err
	}
	return &ast.File{Decls: top.Elts}, nil
}

// All generates an OpenAPI definition from the given instance.
//
// Note: only a limited number of top-level types are supported so far.
// Deprecated: use Generate
func (g *Generator) All(inst *cue.Instance) (*OrderedMap, error) {
	all, err := schemas(g, inst)
	if err != nil {
		return nil, err
	}
	top, err := g.compose(all)
	return (*OrderedMap)(top), err
}

func (c *Config) compose(schemas *ast.StructLit) (*ast.StructLit, error) {
	// Support of OrderedMap is mostly for backwards compatibility.
	var info ast.Expr
	switch x := c.Info.(type) {
	case nil:
		info = ast.NewStruct()
	case ast.Expr:
		info = x
	case *OrderedMap:
		info = (*ast.StructLit)(x)
	case OrderedMap:
		info = (*ast.StructLit)(&x)
	default:
		b, err := json.Marshal(x)
		if err == nil {
			info, err = cuejson.Extract("info", b)
		}
		if err != nil {
			return nil, errors.Wrapf(err, token.NoPos,
				"openapi: could not encode info section")
		}
	}

	return ast.NewStruct(
		"openapi", ast.NewString("3.0.0"),
		"info", info,
		"paths", ast.NewStruct(),
		"components", ast.NewStruct("schemas", schemas),
	), nil
}

// Schemas extracts component/schemas from the CUE top-level types.
func (g *Generator) Schemas(inst *cue.Instance) (*OrderedMap, error) {
	comps, err := schemas(g, inst)
	if err != nil {
		return nil, err
	}
	return (*OrderedMap)(comps), err
}

var defaultConfig = &Config{}

// TODO
// The conversion interprets @openapi(<entry> {, <entry>}) attributes as follows:
//
//      readOnly        sets the readOnly flag for a property in the schema
//                      only one of readOnly and writeOnly may be set.
//      writeOnly       sets the writeOnly flag for a property in the schema
//                      only one of readOnly and writeOnly may be set.
//      discriminator   explicitly sets a field as the discriminator field
//
