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

// Attr holds positional information for a single Attr.
type Attr struct {
	Body   string
	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) {
	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
}
