// Copyright 2017 Google LLC
//
// 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 firestore

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"sync"

	"cloud.google.com/go/internal/fields"
	pb "google.golang.org/genproto/googleapis/firestore/v1beta1"
)

// A FieldPath is a non-empty sequence of non-empty fields that reference a value.
//
// A FieldPath value should only be necessary if one of the field names contains
// one of the runes ".˜*/[]". Most methods accept a simpler form of field path
// as a string in which the individual fields are separated by dots.
// For example,
//   []string{"a", "b"}
// is equivalent to the string form
//   "a.b"
// but
//   []string{"*"}
// has no equivalent string form.
type FieldPath []string

// parseDotSeparatedString constructs a FieldPath from a string that separates
// path components with dots. Other than splitting at dots and checking for invalid
// characters, it ignores everything else about the string,
// including attempts to quote field path compontents. So "a.`b.c`.d" is parsed into
// four parts, "a", "`b", "c`" and "d".
func parseDotSeparatedString(s string) (FieldPath, error) {
	const invalidRunes = "~*/[]"
	if strings.ContainsAny(s, invalidRunes) {
		return nil, fmt.Errorf("firestore: %q contains an invalid rune (one of %s)", s, invalidRunes)
	}
	fp := FieldPath(strings.Split(s, "."))
	if err := fp.validate(); err != nil {
		return nil, err
	}
	return fp, nil
}

func (fp1 FieldPath) equal(fp2 FieldPath) bool {
	if len(fp1) != len(fp2) {
		return false
	}
	for i, c1 := range fp1 {
		if c1 != fp2[i] {
			return false
		}
	}
	return true
}

func (fp1 FieldPath) prefixOf(fp2 FieldPath) bool {
	return len(fp1) <= len(fp2) && fp1.equal(fp2[:len(fp1)])
}

// Lexicographic ordering.
func (fp1 FieldPath) less(fp2 FieldPath) bool {
	for i := range fp1 {
		switch {
		case i >= len(fp2):
			return false
		case fp1[i] < fp2[i]:
			return true
		case fp1[i] > fp2[i]:
			return false
		}
	}
	// fp1 and fp2 are equal up to len(fp1).
	return len(fp1) < len(fp2)
}

// validate checks the validity of fp and returns an error if it is invalid.
func (fp FieldPath) validate() error {
	if len(fp) == 0 {
		return errors.New("firestore: empty field path")
	}
	for _, c := range fp {
		if len(c) == 0 {
			return errors.New("firestore: empty component in field path")
		}
	}
	return nil
}

// with creates a new FieldPath consisting of fp followed by k.
func (fp FieldPath) with(k string) FieldPath {
	r := make(FieldPath, len(fp), len(fp)+1)
	copy(r, fp)
	return append(r, k)
}

// checkNoDupOrPrefix checks whether any FieldPath is a prefix of (or equal to)
// another.
// It modifies the order of FieldPaths in its argument (via sorting).
func checkNoDupOrPrefix(fps []FieldPath) error {
	// Sort fps lexicographically.
	sort.Sort(byPath(fps))
	// Check adjacent pairs for prefix.
	for i := 1; i < len(fps); i++ {
		if fps[i-1].prefixOf(fps[i]) {
			return fmt.Errorf("field path %v cannot be used in the same update as %v", fps[i-1], fps[i])
		}
	}
	return nil
}

type byPath []FieldPath

func (b byPath) Len() int           { return len(b) }
func (b byPath) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
func (b byPath) Less(i, j int) bool { return b[i].less(b[j]) }

// setAtPath sets val at the location in m specified by fp, creating sub-maps as
// needed. m must not be nil. fp is assumed to be valid.
func setAtPath(m map[string]*pb.Value, fp FieldPath, val *pb.Value) {
	if val == nil {
		return
	}
	if len(fp) == 1 {
		m[fp[0]] = val
	} else {
		v, ok := m[fp[0]]
		if !ok {
			v = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: map[string]*pb.Value{}}}}
			m[fp[0]] = v
		}
		// The type assertion below cannot fail, because setAtPath is only called
		// with either an empty map or one filled by setAtPath itself, and the
		// set of FieldPaths it is called with has been checked to make sure that
		// no path is the prefix of any other.
		setAtPath(v.GetMapValue().Fields, fp[1:], val)
	}
}

// getAtPath gets the value in data referred to by fp. The data argument can
// be a map or a struct.
// Compare with valueAtPath, which does the same thing for a document.
func getAtPath(v reflect.Value, fp FieldPath) (interface{}, error) {
	var err error
	for _, k := range fp {
		v, err = getAtField(v, k)
		if err != nil {
			return nil, err
		}
	}
	return v.Interface(), nil
}

// getAtField returns the equivalent of v[k], if v is a map, or v.k if v is a struct.
func getAtField(v reflect.Value, k string) (reflect.Value, error) {
	switch v.Kind() {
	case reflect.Map:
		if r := v.MapIndex(reflect.ValueOf(k)); r.IsValid() {
			return r, nil
		}

	case reflect.Struct:
		fm, err := fieldMap(v.Type())
		if err != nil {
			return reflect.Value{}, err
		}
		if f, ok := fm[k]; ok {
			return v.FieldByIndex(f.Index), nil
		}

	case reflect.Interface:
		return getAtField(v.Elem(), k)

	case reflect.Ptr:
		return getAtField(v.Elem(), k)
	}
	return reflect.Value{}, fmt.Errorf("firestore: no field %q for value %#v", k, v)
}

// fieldMapCache holds maps from from Firestore field name to struct field,
// keyed by struct type.
var fieldMapCache sync.Map

func fieldMap(t reflect.Type) (map[string]fields.Field, error) {
	x, ok := fieldMapCache.Load(t)
	if !ok {
		fieldList, err := fieldCache.Fields(t)
		if err != nil {
			x = err
		} else {
			m := map[string]fields.Field{}
			for _, f := range fieldList {
				m[f.Name] = f
			}
			x = m
		}
		fieldMapCache.Store(t, x)
	}
	if err, ok := x.(error); ok {
		return nil, err
	}
	return x.(map[string]fields.Field), nil
}

// toServiceFieldPath converts fp the form required by the Firestore service.
// It assumes fp has been validated.
func (fp FieldPath) toServiceFieldPath() string {
	cs := make([]string, len(fp))
	for i, c := range fp {
		cs[i] = toServiceFieldPathComponent(c)
	}
	return strings.Join(cs, ".")
}

func toServiceFieldPaths(fps []FieldPath) []string {
	var sfps []string
	for _, fp := range fps {
		sfps = append(sfps, fp.toServiceFieldPath())
	}
	return sfps
}

// Google SQL syntax for an unquoted field.
var unquotedFieldRegexp = regexp.MustCompile("^[A-Za-z_][A-Za-z_0-9]*$")

// toServiceFieldPathComponent returns a string that represents key and is a valid
// field path component.
func toServiceFieldPathComponent(key string) string {
	if unquotedFieldRegexp.MatchString(key) {
		return key
	}
	var buf bytes.Buffer
	buf.WriteRune('`')
	for _, r := range key {
		if r == '`' || r == '\\' {
			buf.WriteRune('\\')
		}
		buf.WriteRune(r)
	}
	buf.WriteRune('`')
	return buf.String()
}
