// Copyright 2018 The 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 adt

import (
	"fmt"
	"math/bits"
	"strings"
)

// Concreteness is a measure of the level of concreteness of a value, where
// lower values mean more concrete.
type Concreteness int

const (
	BottomLevel Concreteness = iota

	// Concrete indicates a concrete scalar value, list or struct.
	Concrete

	// Constraint indicates a non-concrete scalar value that is more specific,
	// than a top-level type.
	Constraint

	// PrimitiveType indicates a top-level specific type, for instance, string,
	// bytes, number, or bool.
	Type

	// Any indicates any value, or top.
	Any
)

// IsConcrete returns whether a value is concrete.
func IsConcrete(v Value) bool {
	if x, ok := v.(*Vertex); ok {
		return x.IsConcrete()
	}
	if v == nil {
		return false
	}
	return v.Concreteness() <= Concrete
}

// Kind reports the Value kind.
type Kind uint16

const (
	NullKind Kind = (1 << iota)
	BoolKind
	IntKind
	FloatKind
	StringKind
	BytesKind
	ListKind
	StructKind

	allKinds

	_numberKind

	NumberKind = IntKind | FloatKind

	BottomKind Kind = 0

	NumKind          = IntKind | FloatKind
	TopKind     Kind = (allKinds - 1) // all kinds, but not references
	ScalarKinds      = NullKind | BoolKind |
		IntKind | FloatKind | StringKind | BytesKind
)

func kind(v Value) Kind {
	if v == nil {
		return BottomKind
	}
	return v.Kind()
}

// IsAnyOf reports whether k is any of the given kinds.
//
// For instances, k.IsAnyOf(String|Bytes) reports whether k overlaps with
// the String or Bytes kind.
func (k Kind) IsAnyOf(of Kind) bool {
	return k&of != BottomKind
}

// CanString reports whether the given type can convert to a string.
func (k Kind) CanString() bool {
	return k&StringKind|ScalarKinds != BottomKind
}

// String returns the representation of the Kind as
// a CUE expression. For example:
//
//	(IntKind|ListKind).String()
//
// will return:
//
//	(int|[...])
func (k Kind) String() string {
	return toString(k, kindStrs)
}

// TypeString is like String, but returns a string representation of a valid
// CUE type.
func (k Kind) TypeString() string {
	return toString(k, typeStrs)
}

func toString(k Kind, m map[Kind]string) string {
	if k == BottomKind {
		return "_|_"
	}
	if k == TopKind {
		return "_"
	}
	if (k & NumberKind) == NumberKind {
		k = (k &^ NumberKind) | _numberKind
	}
	var buf strings.Builder
	multiple := bits.OnesCount(uint(k)) > 1
	if multiple {
		buf.WriteByte('(')
	}
	for count := 0; ; count++ {
		n := bits.TrailingZeros(uint(k))
		if n == bits.UintSize {
			break
		}
		bit := Kind(1 << uint(n))
		k &^= bit
		s, ok := m[bit]
		if !ok {
			s = fmt.Sprintf("bad(%d)", n)
		}
		if count > 0 {
			buf.WriteByte('|')
		}
		buf.WriteString(s)
	}
	if multiple {
		buf.WriteByte(')')
	}
	return buf.String()
}

var kindStrs = map[Kind]string{
	NullKind:    "null",
	BoolKind:    "bool",
	IntKind:     "int",
	FloatKind:   "float",
	StringKind:  "string",
	BytesKind:   "bytes",
	StructKind:  "struct",
	ListKind:    "list",
	_numberKind: "number",
}

// used to generate a parseable CUE type.
var typeStrs = map[Kind]string{
	NullKind:    "null",
	BoolKind:    "bool",
	IntKind:     "int",
	FloatKind:   "float",
	StringKind:  "string",
	BytesKind:   "bytes",
	StructKind:  "{...}",
	ListKind:    "[...]",
	_numberKind: "number",
}
