// 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 (
	"fmt"
	"strings"

	"github.com/cockroachdb/apd/v2"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/token"
)

// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#data-types
var cueToOpenAPI = map[string]string{
	"int32": "int32",
	"int64": "int64",

	"float64": "double",
	"float32": "float",

	"bytes": "binary",

	"time.Time()":                "date-time",
	"time.Time":                  "date-time",
	`time.Format ("2006-01-02")`: "date",

	// TODO: if a format is more strict (e.g. using zeros instead of nines
	// for fractional seconds), we could still use this as an approximation.
	`time.Format ("2006-01-02T15:04:05.999999999Z07:00")`: "date-time",

	// TODO:  password.

	">=-2147483648 & <=2147483647 & int":                                                                   "int32",
	">=-9223372036854775808 & <=9223372036854775807 & int":                                                 "int64",
	">=-340282346638528859811704183484516925440.0 & <=340282346638528859811704183484516925440.0":           "float",
	">=-1.797693134862315708145274237317043567981e+308 & <=1.797693134862315708145274237317043567981e+308": "double",
}

func extractFormat(v cue.Value) string {
	switch k := v.IncompleteKind(); {
	case k&cue.NumberKind != 0, k&cue.StringKind != 0, k&cue.BytesKind != 0:
	default:
		return ""
	}
	var expr, arg string
	op, a := v.Expr()
	if op == cue.CallOp {
		v = a[0]
		if len(a) == 2 {
			arg = fmt.Sprintf(" (%v)", a[1].Eval())
		}
	}
	if inst, ref := v.Reference(); len(ref) > 0 {
		expr = inst.ImportPath + "." + strings.Join(ref, ".")
		expr += arg
	} else {
		expr = fmt.Sprint(v.Eval())
		expr += arg
	}
	if s, ok := cueToOpenAPI[expr]; ok {
		return s
	}
	s := fmt.Sprint(v)
	return cueToOpenAPI[s]
}

func getDeprecated(v cue.Value) bool {
	// only looking at protobuf attribute for now.
	a := v.Attribute("protobuf")
	r, _ := a.Flag(1, "deprecated")
	return r
}

func simplify(b *builder, t *ast.StructLit) {
	if b.format == "" {
		return
	}
	switch b.typ {
	case "number", "integer":
		simplifyNumber(t, b.format)
	}
}

func simplifyNumber(t *ast.StructLit, format string) string {
	fields := t.Elts
	k := 0
	for i, d := range fields {
		switch label(d) {
		case "minimum":
			if decimalEqual(minMap[format], value(d)) {
				continue
			}
		case "maximum":
			if decimalEqual(maxMap[format], value(d)) {
				continue
			}
		}
		fields[k] = fields[i]
		k++
	}
	t.Elts = fields[:k]
	return format
}

func decimalEqual(d *apd.Decimal, v ast.Expr) bool {
	if d == nil {
		return false
	}
	lit, ok := v.(*ast.BasicLit)
	if !ok || (lit.Kind != token.INT && lit.Kind != token.FLOAT) {
		return false
	}
	n := literal.NumInfo{}
	if literal.ParseNum(lit.Value, &n) != nil {
		return false
	}
	var b apd.Decimal
	if n.Decimal(&b) != nil {
		return false
	}
	return d.Cmp(&b) == 0
}

func mustDecimal(s string) *apd.Decimal {
	d, _, err := apd.NewFromString(s)
	if err != nil {
		panic(err)
	}
	return d
}

var (
	minMap = map[string]*apd.Decimal{
		"int32":  mustDecimal("-2147483648"),
		"int64":  mustDecimal("-9223372036854775808"),
		"float":  mustDecimal("-3.40282346638528859811704183484516925440e+38"),
		"double": mustDecimal("-1.797693134862315708145274237317043567981e+308"),
	}
	maxMap = map[string]*apd.Decimal{
		"int32":  mustDecimal("2147483647"),
		"int64":  mustDecimal("9223372036854775807"),
		"float":  mustDecimal("+3.40282346638528859811704183484516925440e+38"),
		"double": mustDecimal("+1.797693134862315708145274237317043567981e+308"),
	}
)
