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

import (
	"fmt"
	"strconv"
	"strings"
	"unicode"

	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/token"
)

// AttrKind indicates the location of an attribute within CUE source.
type AttrKind uint8

const (
	// FieldAttr indicates an attribute is a field attribute.
	// foo: bar @attr()
	FieldAttr AttrKind = 1 << iota

	// DeclAttr indicates an attribute was specified at a declaration position.
	// foo: {
	//     @attr()
	// }
	DeclAttr

	// TODO: Possible future attr kinds
	// ElemAttr
	// FileAttr
	// ValueAttr = FieldAttr|DeclAttr|ElemAttr
)

// Attr holds positional information for a single Attr.
type Attr struct {
	Name   string // e.g. "json" or "protobuf"
	Body   string
	Kind   AttrKind
	Fields []KeyValue
	Err    error
}

// NewNonExisting creates a non-existing attribute.
func NewNonExisting(key string) Attr {
	const msgNotExist = "attribute %q does not exist"
	return Attr{Err: errors.Newf(token.NoPos, msgNotExist, key)}
}

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 {
	if kv.equal == 0 {
		return kv.data
	}
	s := kv.data[:kv.equal]
	s = strings.TrimSpace(s)
	return s
}
func (kv *KeyValue) Value() string {
	if kv.equal == 0 {
		return ""
	}
	return strings.TrimSpace(kv.data[kv.equal+1:])
}

func (a *Attr) hasPos(p int) error {
	if a.Err != nil {
		return a.Err
	}
	if p >= len(a.Fields) {
		return fmt.Errorf("field does not exist")
	}
	return nil
}

// String reports the possibly empty string value at the given position or
// an error the attribute is invalid or if the position does not exist.
func (a *Attr) String(pos int) (string, error) {
	if err := a.hasPos(pos); err != nil {
		return "", err
	}
	return a.Fields[pos].Text(), nil
}

// Int reports the integer at the given position or an error if the attribute is
// invalid, the position does not exist, or the value at the given position is
// not an integer.
func (a *Attr) Int(pos int) (int64, error) {
	if err := a.hasPos(pos); err != nil {
		return 0, err
	}
	// TODO: use CUE's literal parser once it exists, allowing any of CUE's
	// number types.
	return strconv.ParseInt(a.Fields[pos].Text(), 10, 64)
}

// Flag reports whether an entry with the given name exists at position pos or
// onwards or an error if the attribute is invalid or if the first pos-1 entries
// are not defined.
func (a *Attr) Flag(pos int, key string) (bool, error) {
	if err := a.hasPos(pos - 1); err != nil {
		return false, err
	}
	for _, kv := range a.Fields[pos:] {
		if kv.Text() == key {
			return true, nil
		}
	}
	return false, nil
}

// Lookup searches for an entry of the form key=value from position pos onwards
// and reports the value if found. It reports an error if the attribute is
// invalid or if the first pos-1 entries are not defined.
func (a *Attr) Lookup(pos int, key string) (val string, found bool, err error) {
	if err := a.hasPos(pos - 1); err != nil {
		return "", false, err
	}
	for _, kv := range a.Fields[pos:] {
		if kv.Key() == key {
			return kv.Value(), true, nil
		}
	}
	return "", false, nil
}

func ParseAttrBody(pos token.Pos, s string) (a Attr) {
	a.Body = s
	i := 0
	for {
		i += skipSpace(s[i:])
		// always scan at least one, possibly empty element.
		n, err := scanAttributeElem(pos, s[i:], &a)
		if err != nil {
			return Attr{Err: err}
		}
		if i += n; i >= len(s) {
			break
		}
		i += skipSpace(s[i:])
		if s[i] != ',' {
			return Attr{Err: errors.Newf(pos, "invalid attribute: expected comma")}
		}
		i++
	}
	return a
}

func skipSpace(s string) int {
	for n, r := range s {
		if !unicode.IsSpace(r) {
			return n
		}
	}
	return 0
}

func scanAttributeElem(pos token.Pos, s string, a *Attr) (n int, err errors.Error) {
	// try CUE string
	kv := KeyValue{}
	if n, kv.data, err = scanAttributeString(pos, s); n == 0 {
		// try key-value pair
		p := strings.IndexAny(s, ",=") // ) is assumed to be stripped.
		switch {
		case p < 0:
			kv.data = strings.TrimSpace(s)
			n = len(s)

		default: // ','
			n = p
			kv.data = strings.TrimSpace(s[:n])

		case s[p] == '=':
			kv.equal = p
			offset := p + 1
			offset += skipSpace(s[offset:])
			var str string
			if p, str, err = scanAttributeString(pos, 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 = strings.TrimSpace(s[:n])
			}
		}
	}
	if a != nil {
		a.Fields = append(a.Fields, kv)
	}
	return n, err
}

func scanAttributeString(pos token.Pos, s string) (n int, str string, err errors.Error) {
	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], errors.Newf(pos, "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), "", errors.Newf(pos, "attribute string not terminated")
	}

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