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

	"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 {
	fields, err := fieldCache.Fields(vs.Type())
	if err != nil {
		return err
	}
	for k, vproto := range pm {
		f := fields.Match(k)
		if f == nil {
			continue
		}
		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())
}
