// Copyright 2021 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 pbinternal

import (
	"strings"

	"cuelang.org/go/cue"
)

type CompositeType int

const (
	Normal CompositeType = iota
	List
	Map
)

type ValueType int

const (
	Unknown ValueType = iota
	Message
	Int
	Float
	String
	Bytes
	Bool
)

type Info struct {
	Name    string
	CUEName string
	Attr    cue.Attribute
	Value   cue.Value

	CompositeType CompositeType
	ValueType     ValueType
	Type          string

	// For maps only
	KeyType       ValueType // only for maps
	KeyTypeString string
}

func FromIter(i *cue.Iterator) (info Info, err error) {
	return FromValue(i.Label(), i.Value())
}

func FromValue(name string, v cue.Value) (info Info, err error) {
	a := v.Attribute("protobuf")

	info.Name = name
	info.CUEName = name

	if a.Err() == nil {
		info.Attr = a

		s, ok, err := a.Lookup(1, "name")
		if err != nil {
			return info, err
		}
		if ok {
			info.Name = strings.TrimSpace(s)
		}

		info.Type, err = a.String(1)
		if err != nil {
			return info, err
		}
	}

	switch v.IncompleteKind() {
	case cue.ListKind:
		info.CompositeType = List
		e, _ := v.Elem()
		if e.Exists() {
			v = e
		} else {
			for i, _ := v.List(); i.Next(); {
				v = i.Value()
				break
			}
		}

	case cue.StructKind:
		if strings.HasPrefix(info.Type, "map[") {
			a := strings.SplitN(info.Type[len("map["):], ",", 2)
			info.KeyTypeString = strings.TrimSpace(a[0])
			switch info.KeyTypeString {
			case "string":
				info.KeyType = String
			case "bytes":
				info.KeyType = Bytes
			case "double", "float":
				info.KeyType = Float
			case "bool":
				info.KeyType = Bool
			default:
				info.KeyType = Int // Assuming
			}
			info.CompositeType = Map
			v, _ = v.Elem()
		}
	}

	info.Value = v

	switch v.IncompleteKind() {
	case cue.StructKind:
		info.ValueType = Message

	case cue.StringKind:
		info.ValueType = String

	case cue.BytesKind:
		info.ValueType = Bytes

	case cue.BoolKind:
		info.ValueType = Bool

	case cue.IntKind:
		info.ValueType = Int

	case cue.FloatKind, cue.NumberKind:
		info.ValueType = Float
	}

	return info, nil
}
