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

import (
	"sort"
	"strings"

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

// This file includes functionality for parsing attributes.
// These functions are slightly more permissive than the spec. Together with the
// scanner and parser the full spec is implemented, though.

// attributes is used to store per-key attribute text for a fields.
// It deliberately does not implement the value interface, as it should
// never act as a value in any way.
type attributes struct {
	attr []attr
}
type attr struct {
	text   string
	offset int
}

func (a *attr) key() string {
	return a.text[1:a.offset]
}

func (a *attr) body() string {
	return a.text[a.offset+1 : len(a.text)-1]
}

func createAttrs(ctx *context, src source, attrs []*ast.Attribute) (a *attributes, err *bottom) {
	if len(attrs) == 0 {
		return nil, nil
	}
	as := []attr{}
	for _, a := range attrs {
		index := strings.IndexByte(a.Text, '(')
		n := len(a.Text)
		if index < 2 || a.Text[0] != '@' || a.Text[n-1] != ')' {
			return nil, ctx.mkErr(newNode(a), "invalid attribute %q", a.Text)
		}
		as = append(as, attr{a.Text[:n], index})

		if err := parseAttrBody(ctx, src, a.Text[index+1:n-1], nil); err != nil {
			return nil, err
		}
	}

	sort.SliceStable(as, func(i, j int) bool { return as[i].text < as[j].text })
	// TODO: remove these restrictions.
	for i := 1; i < len(as); i++ {
		if ai, aj := as[i-1], as[i]; ai.key() == aj.key() {
			n := newNode(attrs[0])
			return nil, ctx.mkErr(n, "multiple attributes for key %q", ai.key())
		}
	}

	return &attributes{as}, nil
}

// unifyAttrs merges the attributes from a and b. It may return either a or b
// if a and b are identical.
func unifyAttrs(ctx *context, src source, a, b *attributes) (atrs *attributes, err evaluated) {
	if a == b {
		return a, nil
	}
	if a == nil {
		return b, nil
	}
	if b == nil {
		return a, nil
	}

	if len(a.attr) == len(b.attr) {
		for i, x := range a.attr {
			if x != b.attr[i] {
				goto notSame
			}
		}
		return a, nil
	}

notSame:
	as := append(a.attr, b.attr...)

	// remove duplicates and error on conflicts
	sort.Slice(as, func(i, j int) bool { return as[i].text < as[j].text })
	k := 0
	for i := 1; i < len(as); i++ {
		if ak, ai := as[k], as[i]; ak.key() == ai.key() {
			if ak.body() == ai.body() {
				continue
			}
			return nil, ctx.mkErr(src, "conflicting attributes for key %q", ai.key())
		}
		k++
		as[k] = as[i]
	}

	return &attributes{as[:k+1]}, nil
}

// parsedAttr holds positional information for a single parsedAttr.
type parsedAttr struct {
	fields []keyValue
}

type keyValue struct {
	data  string
	equal int // index of equal sign or 0 if non-existing
}

func (kv *keyValue) text() string  { return kv.data }
func (kv *keyValue) key() string   { return kv.data[:kv.equal] }
func (kv *keyValue) value() string { return kv.data[kv.equal+1:] }

func parseAttrBody(ctx *context, src source, s string, a *parsedAttr) (err *bottom) {
	i := 0
	for {
		// always scan at least one, possibly empty element.
		n, err := scanAttributeElem(ctx, src, s[i:], a)
		if err != nil {
			return err
		}
		if i += n; i >= len(s) {
			break
		}
		if s[i] != ',' {
			return ctx.mkErr(src, "invalid attribute: expected comma")
		}
		i++
	}
	return nil
}

func scanAttributeElem(ctx *context, src source, s string, a *parsedAttr) (n int, err *bottom) {
	// try CUE string
	kv := keyValue{}
	if n, kv.data, err = scanAttributeString(ctx, src, s); n == 0 {
		// try key-value pair
		p := strings.IndexAny(s, ",=") // ) is assumed to be stripped.
		switch {
		case p < 0:
			kv.data = s
			n = len(s)

		default: // ','
			n = p
			kv.data = s[:n]

		case s[p] == '=':
			kv.equal = p
			offset := p + 1
			var str string
			if p, str, err = scanAttributeString(ctx, src, s[offset:]); p > 0 {
				n = offset + p
				kv.data = s[:offset] + str
			} else {
				n = len(s)
				if p = strings.IndexByte(s[offset:], ','); p >= 0 {
					n = offset + p
				}
				kv.data = s[:n]
			}
		}
	}
	if a != nil {
		a.fields = append(a.fields, kv)
	}
	return n, err
}

func scanAttributeString(ctx *context, src source, s string) (n int, str string, err *bottom) {
	if s == "" || (s[0] != '#' && s[0] != '"' && s[0] != '\'') {
		return 0, "", nil
	}

	nHash := 0
	for {
		if nHash < len(s) {
			if s[nHash] == '#' {
				nHash++
				continue
			}
			if s[nHash] == '\'' || s[nHash] == '"' {
				break
			}
		}
		return nHash, s[:nHash], ctx.mkErr(src, "invalid attribute string")
	}

	// Determine closing quote.
	nQuote := 1
	if c := s[nHash]; nHash+6 < len(s) && s[nHash+1] == c && s[nHash+2] == c {
		nQuote = 3
	}
	close := s[nHash:nHash+nQuote] + s[:nHash]

	// Search for closing quote.
	index := strings.Index(s[len(close):], close)
	if index == -1 {
		return len(s), "", ctx.mkErr(src, "attribute string not terminated")
	}

	index += 2 * len(close)
	s, err2 := literal.Unquote(s[:index])
	if err2 != nil {
		return index, "", ctx.mkErr(src, "invalid attribute string: %v", err2)
	}
	return index, s, nil
}
