// 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 (
	"errors"
	"fmt"
	"reflect"
	"strings"

	"cloud.google.com/go/internal/fields"
	"github.com/golang/protobuf/ptypes"
	pb "google.golang.org/genproto/googleapis/firestore/v1"
)

func setFromProtoValue(x interface{}, vproto *pb.Value, c *Client) error {
	v := reflect.ValueOf(x)
	if v.Kind() != reflect.Ptr || v.IsNil() {
		return errors.New("firestore: nil or not a pointer")
	}
	return setReflectFromProtoValue(v.Elem(), vproto, c)
}

// setReflectFromProtoValue sets v from a Firestore Value.
// v must be a settable value.
func setReflectFromProtoValue(v reflect.Value, vproto *pb.Value, c *Client) error {
	typeErr := func() error {
		return fmt.Errorf("firestore: cannot set type %s to %s", v.Type(), typeString(vproto))
	}

	val := vproto.ValueType
	// A Null value sets anything nullable to nil, and has no effect
	// on anything else.
	if _, ok := val.(*pb.Value_NullValue); ok {
		switch v.Kind() {
		case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
			v.Set(reflect.Zero(v.Type()))
		}
		return nil
	}

	// Handle special types first.
	switch v.Type() {
	case typeOfByteSlice:
		x, ok := val.(*pb.Value_BytesValue)
		if !ok {
			return typeErr()
		}
		v.SetBytes(x.BytesValue)
		return nil

	case typeOfGoTime:
		x, ok := val.(*pb.Value_TimestampValue)
		if !ok {
			return typeErr()
		}
		t, err := ptypes.Timestamp(x.TimestampValue)
		if err != nil {
			return err
		}
		v.Set(reflect.ValueOf(t))
		return nil

	case typeOfProtoTimestamp:
		x, ok := val.(*pb.Value_TimestampValue)
		if !ok {
			return typeErr()
		}
		v.Set(reflect.ValueOf(x.TimestampValue))
		return nil

	case typeOfLatLng:
		x, ok := val.(*pb.Value_GeoPointValue)
		if !ok {
			return typeErr()
		}
		v.Set(reflect.ValueOf(x.GeoPointValue))
		return nil

	case typeOfDocumentRef:
		x, ok := val.(*pb.Value_ReferenceValue)
		if !ok {
			return typeErr()
		}
		dr, err := pathToDoc(x.ReferenceValue, c)
		if err != nil {
			return err
		}
		v.Set(reflect.ValueOf(dr))
		return nil
	}

	switch v.Kind() {
	case reflect.Bool:
		x, ok := val.(*pb.Value_BooleanValue)
		if !ok {
			return typeErr()
		}
		v.SetBool(x.BooleanValue)

	case reflect.String:
		x, ok := val.(*pb.Value_StringValue)
		if !ok {
			return typeErr()
		}
		v.SetString(x.StringValue)

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		var i int64
		switch x := val.(type) {
		case *pb.Value_IntegerValue:
			i = x.IntegerValue
		case *pb.Value_DoubleValue:
			f := x.DoubleValue
			i = int64(f)
			if float64(i) != f {
				return fmt.Errorf("firestore: float %f does not fit into %s", f, v.Type())
			}
		default:
			return typeErr()
		}
		if v.OverflowInt(i) {
			return overflowErr(v, i)
		}
		v.SetInt(i)

	case reflect.Uint8, reflect.Uint16, reflect.Uint32:
		var u uint64
		switch x := val.(type) {
		case *pb.Value_IntegerValue:
			u = uint64(x.IntegerValue)
		case *pb.Value_DoubleValue:
			f := x.DoubleValue
			u = uint64(f)
			if float64(u) != f {
				return fmt.Errorf("firestore: float %f does not fit into %s", f, v.Type())
			}
		default:
			return typeErr()
		}
		if v.OverflowUint(u) {
			return overflowErr(v, u)
		}
		v.SetUint(u)

	case reflect.Float32, reflect.Float64:
		var f float64
		switch x := val.(type) {
		case *pb.Value_DoubleValue:
			f = x.DoubleValue
		case *pb.Value_IntegerValue:
			f = float64(x.IntegerValue)
			if int64(f) != x.IntegerValue {
				return overflowErr(v, x.IntegerValue)
			}
		default:
			return typeErr()
		}
		if v.OverflowFloat(f) {
			return overflowErr(v, f)
		}
		v.SetFloat(f)

	case reflect.Slice:
		x, ok := val.(*pb.Value_ArrayValue)
		if !ok {
			return typeErr()
		}
		vals := x.ArrayValue.Values
		vlen := v.Len()
		xlen := len(vals)
		// Make a slice of the right size, avoiding allocation if possible.
		switch {
		case vlen < xlen:
			v.Set(reflect.MakeSlice(v.Type(), xlen, xlen))
		case vlen > xlen:
			v.SetLen(xlen)
		}
		return populateRepeated(v, vals, xlen, c)

	case reflect.Array:
		x, ok := val.(*pb.Value_ArrayValue)
		if !ok {
			return typeErr()
		}
		vals := x.ArrayValue.Values
		xlen := len(vals)
		vlen := v.Len()
		minlen := vlen
		// Set extra elements to their zero value.
		if vlen > xlen {
			z := reflect.Zero(v.Type().Elem())
			for i := xlen; i < vlen; i++ {
				v.Index(i).Set(z)
			}
			minlen = xlen
		}
		return populateRepeated(v, vals, minlen, c)

	case reflect.Map:
		x, ok := val.(*pb.Value_MapValue)
		if !ok {
			return typeErr()
		}
		return populateMap(v, x.MapValue.Fields, c)

	case reflect.Ptr:
		// If the pointer is nil, set it to a zero value.
		if v.IsNil() {
			v.Set(reflect.New(v.Type().Elem()))
		}
		return setReflectFromProtoValue(v.Elem(), vproto, c)

	case reflect.Struct:
		x, ok := val.(*pb.Value_MapValue)
		if !ok {
			return typeErr()
		}
		return populateStruct(v, x.MapValue.Fields, c)

	case reflect.Interface:
		if v.NumMethod() == 0 { // empty interface
			// If v holds a pointer, set the pointer.
			if !v.IsNil() && v.Elem().Kind() == reflect.Ptr {
				return setReflectFromProtoValue(v.Elem(), vproto, c)
			}
			// Otherwise, create a fresh value.
			x, err := createFromProtoValue(vproto, c)
			if err != nil {
				return err
			}
			v.Set(reflect.ValueOf(x))
			return nil
		}
		// Any other kind of interface is an error.
		fallthrough

	default:
		return fmt.Errorf("firestore: cannot set type %s", v.Type())
	}
	return nil
}

// populateRepeated sets the first n elements of vr, which must be a slice or
// array, to the corresponding elements of vals.
func populateRepeated(vr reflect.Value, vals []*pb.Value, n int, c *Client) error {
	for i := 0; i < n; i++ {
		if err := setReflectFromProtoValue(vr.Index(i), vals[i], c); err != nil {
			return err
		}
	}
	return nil
}

// populateMap sets the elements of vm, which must be a map, from the
// corresponding elements of pm.
//
// Since a map value is not settable, this function always creates a new
// element for each corresponding map key. Existing values of vm are
// overwritten. This happens even if the map value is something like a pointer
// to a struct, where we could in theory populate the existing struct value
// instead of discarding it. This behavior matches encoding/json.
func populateMap(vm reflect.Value, pm map[string]*pb.Value, c *Client) error {
	t := vm.Type()
	if t.Key().Kind() != reflect.String {
		return errors.New("firestore: map key type is not string")
	}
	if vm.IsNil() {
		vm.Set(reflect.MakeMap(t))
	}
	et := t.Elem()
	for k, vproto := range pm {
		el := reflect.New(et).Elem()
		if err := setReflectFromProtoValue(el, vproto, c); err != nil {
			return err
		}
		vm.SetMapIndex(reflect.ValueOf(k), el)
	}
	return nil
}

// createMapFromValueMap creates a fresh map and populates it with pm.
func createMapFromValueMap(pm map[string]*pb.Value, c *Client) (map[string]interface{}, error) {
	m := map[string]interface{}{}
	for k, pv := range pm {
		v, err := createFromProtoValue(pv, c)
		if err != nil {
			return nil, err
		}
		m[k] = v
	}
	return m, nil
}

// populateStruct sets the fields of vs, which must be a struct, from
// the matching elements of pm.
func populateStruct(vs reflect.Value, pm map[string]*pb.Value, c *Client) error {
	fs, err := fieldCache.Fields(vs.Type())
	if err != nil {
		return err
	}

	type match struct {
		vproto *pb.Value
		f      *fields.Field
	}
	// Find best field matches
	matched := make(map[string]match)
	for k, vproto := range pm {
		f := fs.Match(k)
		if f == nil {
			continue
		}
		if _, ok := matched[f.Name]; ok {
			// If multiple case insensitive fields match, the exact match
			// should win.
			if f.Name == k {
				matched[k] = match{vproto: vproto, f: f}
			}
		} else {
			matched[f.Name] = match{vproto: vproto, f: f}
		}
	}

	// Reflect values
	for _, v := range matched {
		f := v.f
		vproto := v.vproto

		if err := setReflectFromProtoValue(vs.FieldByIndex(f.Index), vproto, c); err != nil {
			return fmt.Errorf("%s.%s: %v", vs.Type(), f.Name, err)
		}
	}
	return nil
}

func createFromProtoValue(vproto *pb.Value, c *Client) (interface{}, error) {
	switch v := vproto.ValueType.(type) {
	case *pb.Value_NullValue:
		return nil, nil
	case *pb.Value_BooleanValue:
		return v.BooleanValue, nil
	case *pb.Value_IntegerValue:
		return v.IntegerValue, nil
	case *pb.Value_DoubleValue:
		return v.DoubleValue, nil
	case *pb.Value_TimestampValue:
		return ptypes.Timestamp(v.TimestampValue)
	case *pb.Value_StringValue:
		return v.StringValue, nil
	case *pb.Value_BytesValue:
		return v.BytesValue, nil
	case *pb.Value_ReferenceValue:
		return pathToDoc(v.ReferenceValue, c)
	case *pb.Value_GeoPointValue:
		return v.GeoPointValue, nil
	case *pb.Value_ArrayValue:
		vals := v.ArrayValue.Values
		ret := make([]interface{}, len(vals))
		for i, v := range vals {
			r, err := createFromProtoValue(v, c)
			if err != nil {
				return nil, err
			}
			ret[i] = r
		}
		return ret, nil

	case *pb.Value_MapValue:
		fields := v.MapValue.Fields
		ret := make(map[string]interface{}, len(fields))
		for k, v := range fields {
			r, err := createFromProtoValue(v, c)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		}
		return ret, nil

	default:
		return nil, fmt.Errorf("firestore: unknown value type %T", v)
	}
}

// Convert a document path to a DocumentRef.
func pathToDoc(docPath string, c *Client) (*DocumentRef, error) {
	projID, dbID, docIDs, err := parseDocumentPath(docPath)
	if err != nil {
		return nil, err
	}
	parentResourceName := fmt.Sprintf("projects/%s/databases/%s", projID, dbID)
	_, doc := c.idsToRef(docIDs, parentResourceName)
	return doc, nil
}

// A document path should be of the form "projects/P/databases/D/documents/coll1/doc1/coll2/doc2/...".
func parseDocumentPath(path string) (projectID, databaseID string, docPath []string, err error) {
	parts := strings.Split(path, "/")
	if len(parts) < 6 || parts[0] != "projects" || parts[2] != "databases" || parts[4] != "documents" {
		return "", "", nil, fmt.Errorf("firestore: malformed document path %q", path)
	}
	docp := parts[5:]
	if len(docp)%2 != 0 {
		return "", "", nil, fmt.Errorf("firestore: path %q refers to collection, not document", path)
	}
	return parts[1], parts[3], docp, nil
}

func typeString(vproto *pb.Value) string {
	switch vproto.ValueType.(type) {
	case *pb.Value_NullValue:
		return "null"
	case *pb.Value_BooleanValue:
		return "bool"
	case *pb.Value_IntegerValue:
		return "int"
	case *pb.Value_DoubleValue:
		return "float"
	case *pb.Value_TimestampValue:
		return "timestamp"
	case *pb.Value_StringValue:
		return "string"
	case *pb.Value_BytesValue:
		return "bytes"
	case *pb.Value_ReferenceValue:
		return "reference"
	case *pb.Value_GeoPointValue:
		return "GeoPoint"
	case *pb.Value_MapValue:
		return "map"
	case *pb.Value_ArrayValue:
		return "array"
	default:
		return "<unknown Value type>"
	}
}

func overflowErr(v reflect.Value, x interface{}) error {
	return fmt.Errorf("firestore: value %v overflows type %s", x, v.Type())
}
