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

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

// Attr holds positional information for a single Attr.
type Attr struct {
	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  { return kv.data[:kv.equal] }
func (kv *keyValue) Value() string {
	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) {
	i := 0
	for {
		// 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
		}
		if s[i] != ',' {
			return Attr{Err: errors.Newf(pos, "invalid attribute: expected comma")}
		}
		i++
	}
	return a
}

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 = 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(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 = 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
}
