// Copyright 2020 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 compile

import (
	"github.com/cockroachdb/apd/v2"
	"golang.org/x/text/unicode/norm"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal/core/adt"
)

// LabelFromNode converts an ADT node to a feature.
func (c *compiler) label(n ast.Node) adt.Feature {
	index := c.index
	switch x := n.(type) {
	case *ast.Ident:
		return adt.MakeIdentLabel(c.index, x.Name, c.pkgPath)

	case *ast.BasicLit:
		switch x.Kind {
		case token.STRING:
			const msg = "invalid string label: %v"
			s, err := literal.Unquote(x.Value)
			if err != nil {
				c.errf(n, msg, err)
				return adt.InvalidLabel
			}

			i := int64(index.StringToIndex(norm.NFC.String(s)))
			f, err := adt.MakeLabel(n, i, adt.StringLabel)
			if err != nil {
				c.errf(n, msg, err)
			}
			return f

		case token.INT:
			const msg = "invalid int label: %v"
			if err := literal.ParseNum(x.Value, &c.num); err != nil {
				c.errf(n, msg, err)
				return adt.InvalidLabel
			}

			var d apd.Decimal
			if err := c.num.Decimal(&d); err != nil {
				c.errf(n, msg, err)
				return adt.InvalidLabel
			}

			i, err := d.Int64()
			if err != nil {
				c.errf(n, msg, err)
				return adt.InvalidLabel
			}

			f, err := adt.MakeLabel(n, i, adt.IntLabel)
			if err != nil {
				c.errf(n, msg, err)
				return adt.InvalidLabel
			}
			return f

		case token.FLOAT:
			_ = c.errf(n, "float %s cannot be used as label", x.Value)
			return adt.InvalidLabel

		default: // keywords (null, true, false, for, in, if, let)
			i := index.StringToIndex(x.Kind.String())
			f, err := adt.MakeLabel(n, i, adt.StringLabel)
			if err != nil {
				c.errf(n, "invalid string label: %v", err)
			}
			return f
		}

	default:
		c.errf(n, "unsupported label node type %T", n)
		return adt.InvalidLabel
	}
}

// A labeler converts an AST node to a string representation.
type labeler interface {
	labelString() string
}

type fieldLabel ast.Field

func (l *fieldLabel) labelString() string {
	lab := l.Label

	if a, ok := lab.(*ast.Alias); ok {
		if x, _ := a.Expr.(ast.Label); x != nil {
			lab = x
		}
	}

	switch x := lab.(type) {
	case *ast.Ident:
		return x.Name

	case *ast.BasicLit:
		if x.Kind == token.STRING {
			s, err := literal.Unquote(x.Value)
			if err == nil && ast.IsValidIdent(s) {
				return s
			}
		}
		return x.Value

	case *ast.ListLit:
		return "[]" // TODO: more detail

	case *ast.Interpolation:
		return "?"
		// case *ast.ParenExpr:
	}
	return "<unknown>"
}

type forScope ast.ForClause

func (l *forScope) labelString() string {
	// TODO: include more info in square brackets.
	return "for[]"
}

type letScope ast.LetClause

func (l *letScope) labelString() string {
	// TODO: include more info in square brackets.
	return "let[]"
}
