// 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.Slice(as, func(i, j int) bool { return as[i].text < as[j].text })
	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
}
