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

// This file contains functionality for structural schema, a subset of OpenAPI
// used for CRDs.
//
// See https://kubernetes.io/blog/2019/06/20/crd-structural-schema/ for details.
//
// Insofar definitions are compatible, openapi normalizes to structural whenever
// possible.
//
// A core structural schema is only made out of the following fields:
//
// - properties
// - items
// - additionalProperties
// - type
// - nullable
// - title
// - descriptions.
//
// Where the types must be defined for all fields.
//
// In addition, the value validations constraints may be used as defined in
// OpenAPI, with the restriction that
//  - within the logical constraints anyOf, allOf, oneOf, and not
//    additionalProperties, type, nullable, title, and description may not be used.
//  - all mentioned fields must be defined in the core schema.
//
// It appears that CRDs do not allow references.
//

import (
	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
)

// newCoreBuilder returns a builder that represents a structural schema.
func newCoreBuilder(c *buildContext) *builder {
	b := newRootBuilder(c)
	b.properties = map[string]*builder{}
	return b
}

// coreSchema creates the core part of a structural OpenAPI.
func (b *builder) coreSchema(name string) *ast.StructLit {
	oldPath := b.ctx.path
	b.ctx.path = append(b.ctx.path, name)
	defer func() { b.ctx.path = oldPath }()

	switch b.kind {
	case cue.ListKind:
		if b.items != nil {
			b.setType("array", "")
			schema := b.items.coreSchema("*")
			b.setSingle("items", schema, false)
		}

	case cue.StructKind:
		p := &OrderedMap{}
		for _, k := range b.keys {
			sub := b.properties[k]
			p.Set(k, sub.coreSchema(k))
		}
		if p.len() > 0 || b.items != nil {
			b.setType("object", "")
		}
		if p.len() > 0 {
			b.setSingle("properties", (*ast.StructLit)(p), false)
		}
		// TODO: in Structural schema only one of these is allowed.
		if b.items != nil {
			schema := b.items.coreSchema("*")
			b.setSingle("additionalProperties", schema, false)
		}
	}

	// If there was only a single value associated with this node, we can
	// safely assume there were no disjunctions etc. In structural mode this
	// is the only chance we get to set certain properties.
	if len(b.values) == 1 {
		return b.fillSchema(b.values[0])
	}

	// TODO: do type analysis if we have multiple values and piece out more
	// information that applies to all possible instances.

	return b.finish()
}

// buildCore collects the CUE values for the structural OpenAPI tree.
// To this extent, all fields of both conjunctions and disjunctions are
// collected in a single properties map.
func (b *builder) buildCore(v cue.Value) {
	if !b.ctx.expandRefs {
		_, r := v.Reference()
		if len(r) > 0 {
			return
		}
	}
	b.getDoc(v)
	format := extractFormat(v)
	if format != "" {
		b.format = format
	} else {
		v = v.Eval()
		b.kind = v.IncompleteKind()

		switch b.kind {
		case cue.StructKind:
			if typ, ok := v.Elem(); ok {
				if b.items == nil {
					b.items = newCoreBuilder(b.ctx)
				}
				b.items.buildCore(typ)
			}
			b.buildCoreStruct(v)

		case cue.ListKind:
			if typ, ok := v.Elem(); ok {
				if b.items == nil {
					b.items = newCoreBuilder(b.ctx)
				}
				b.items.buildCore(typ)
			}
		}
	}

	for _, bv := range b.values {
		if bv.Equals(v) {
			return
		}
	}
	b.values = append(b.values, v)
}

func (b *builder) buildCoreStruct(v cue.Value) {
	op, args := v.Expr()
	switch op {
	case cue.OrOp, cue.AndOp:
		for _, v := range args {
			b.buildCore(v)
		}
	}
	for i, _ := v.Fields(cue.Optional(true), cue.Hidden(false)); i.Next(); {
		label := i.Label()
		sub, ok := b.properties[label]
		if !ok {
			sub = newCoreBuilder(b.ctx)
			b.properties[label] = sub
			b.keys = append(b.keys, label)
		}
		sub.buildCore(i.Value())
	}
}
