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

	"cloud.google.com/go/internal/fields"
	"github.com/golang/protobuf/ptypes"
	ts "github.com/golang/protobuf/ptypes/timestamp"
	pb "google.golang.org/genproto/googleapis/firestore/v1beta1"
	"google.golang.org/genproto/googleapis/type/latlng"
)

var nullValue = &pb.Value{ValueType: &pb.Value_NullValue{}}

var (
	typeOfByteSlice      = reflect.TypeOf([]byte{})
	typeOfGoTime         = reflect.TypeOf(time.Time{})
	typeOfLatLng         = reflect.TypeOf((*latlng.LatLng)(nil))
	typeOfDocumentRef    = reflect.TypeOf((*DocumentRef)(nil))
	typeOfProtoTimestamp = reflect.TypeOf((*ts.Timestamp)(nil))
)

// toProtoValue converts a Go value to a Firestore Value protobuf.
// Some corner cases:
// - All nils (nil interface, nil slice, nil map, nil pointer) are converted to
//   a NullValue (not a nil *pb.Value). toProtoValue never returns (nil, false, nil).
//   It returns (nil, true, nil) if everything in the value is ServerTimestamp.
// - An error is returned for uintptr, uint and uint64, because Firestore uses
//   an int64 to represent integral values, and those types can't be properly
//   represented in an int64.
// - An error is returned for the special Delete value.
//
// toProtoValue also reports whether it recursively encountered a transform.
func toProtoValue(v reflect.Value) (pbv *pb.Value, sawTransform bool, err error) {
	if !v.IsValid() {
		return nullValue, false, nil
	}
	vi := v.Interface()
	if vi == Delete {
		return nil, false, errors.New("firestore: cannot use Delete in value")
	}
	if vi == ServerTimestamp {
		return nil, false, errors.New("firestore: must use ServerTimestamp as a map value")
	}
	switch x := vi.(type) {
	case []byte:
		return &pb.Value{ValueType: &pb.Value_BytesValue{x}}, false, nil
	case time.Time:
		ts, err := ptypes.TimestampProto(x)
		if err != nil {
			return nil, false, err
		}
		return &pb.Value{ValueType: &pb.Value_TimestampValue{ts}}, false, nil
	case *ts.Timestamp:
		if x == nil {
			// gRPC doesn't like nil oneofs. Use NullValue.
			return nullValue, false, nil
		}
		return &pb.Value{ValueType: &pb.Value_TimestampValue{x}}, false, nil
	case *latlng.LatLng:
		if x == nil {
			// gRPC doesn't like nil oneofs. Use NullValue.
			return nullValue, false, nil
		}
		return &pb.Value{ValueType: &pb.Value_GeoPointValue{x}}, false, nil
	case *DocumentRef:
		if x == nil {
			// gRPC doesn't like nil oneofs. Use NullValue.
			return nullValue, false, nil
		}
		return &pb.Value{ValueType: &pb.Value_ReferenceValue{x.Path}}, false, nil
		// Do not add bool, string, int, etc. to this switch; leave them in the
		// reflect-based switch below. Moving them here would drop support for
		// types whose underlying types are those primitives.
		// E.g. Given "type mybool bool", an ordinary type switch on bool will
		// not catch a mybool, but the reflect.Kind of a mybool is reflect.Bool.
	}
	switch v.Kind() {
	case reflect.Bool:
		return &pb.Value{ValueType: &pb.Value_BooleanValue{v.Bool()}}, false, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return &pb.Value{ValueType: &pb.Value_IntegerValue{v.Int()}}, false, nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32:
		return &pb.Value{ValueType: &pb.Value_IntegerValue{int64(v.Uint())}}, false, nil
	case reflect.Float32, reflect.Float64:
		return &pb.Value{ValueType: &pb.Value_DoubleValue{v.Float()}}, false, nil
	case reflect.String:
		return &pb.Value{ValueType: &pb.Value_StringValue{v.String()}}, false, nil
	case reflect.Slice:
		return sliceToProtoValue(v)
	case reflect.Map:
		return mapToProtoValue(v)
	case reflect.Struct:
		return structToProtoValue(v)
	case reflect.Ptr:
		if v.IsNil() {
			return nullValue, false, nil
		}
		return toProtoValue(v.Elem())
	case reflect.Interface:
		if v.NumMethod() == 0 { // empty interface: recurse on its contents
			return toProtoValue(v.Elem())
		}
		fallthrough // any other interface value is an error

	default:
		return nil, false, fmt.Errorf("firestore: cannot convert type %s to value", v.Type())
	}
}

// sliceToProtoValue converts a slice to a Firestore Value protobuf and reports
// whether a transform was encountered.
func sliceToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
	// A nil slice is converted to a null value.
	if v.IsNil() {
		return nullValue, false, nil
	}
	vals := make([]*pb.Value, v.Len())
	for i := 0; i < v.Len(); i++ {
		val, sawTransform, err := toProtoValue(v.Index(i))
		if err != nil {
			return nil, false, err
		}
		if sawTransform {
			return nil, false, fmt.Errorf("firestore: transforms cannot occur in an array, but saw some in %v", v.Index(i))
		}
		vals[i] = val
	}
	return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: vals}}}, false, nil
}

// mapToProtoValue converts a map to a Firestore Value protobuf and reports whether
// a transform was encountered.
func mapToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
	if v.Type().Key().Kind() != reflect.String {
		return nil, false, errors.New("firestore: map key type must be string")
	}
	// A nil map is converted to a null value.
	if v.IsNil() {
		return nullValue, false, nil
	}
	m := map[string]*pb.Value{}
	sawTransform := false
	for _, k := range v.MapKeys() {
		mi := v.MapIndex(k)
		if mi.Interface() == ServerTimestamp {
			sawTransform = true
			continue
		} else if _, ok := mi.Interface().(arrayUnion); ok {
			sawTransform = true
			continue
		} else if _, ok := mi.Interface().(arrayRemove); ok {
			sawTransform = true
			continue
		}
		val, sst, err := toProtoValue(mi)
		if err != nil {
			return nil, false, err
		}
		if sst {
			sawTransform = true
		}
		if val == nil { // value was a map with all ServerTimestamp values
			continue
		}
		m[k.String()] = val
	}
	var pv *pb.Value
	if len(m) == 0 && sawTransform {
		// The entire map consisted of transform values.
		pv = nil
	} else {
		pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
	}
	return pv, sawTransform, nil
}

// structToProtoValue converts a struct to a Firestore Value protobuf and reports
// whether a transform was encountered.
func structToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
	m := map[string]*pb.Value{}
	fields, err := fieldCache.Fields(v.Type())
	if err != nil {
		return nil, false, err
	}
	sawTransform := false
	if _, ok := v.Interface().(arrayUnion); ok {
		return nil, false, errors.New("firestore: ArrayUnion may not be used in structs")
	}
	if _, ok := v.Interface().(arrayRemove); ok {
		return nil, false, errors.New("firestore: ArrayRemove may not be used in structs")
	}

	for _, f := range fields {
		fv := v.FieldByIndex(f.Index)
		opts := f.ParsedTag.(tagOptions)
		if opts.serverTimestamp {
			// TODO(jba): should we return a non-zero time?
			sawTransform = true
			continue
		}
		if opts.omitEmpty && isEmptyValue(fv) {
			continue
		}
		val, sst, err := toProtoValue(fv)
		if err != nil {
			return nil, false, err
		}
		if sst {
			sawTransform = true
		}
		if val == nil { // value was a map with all ServerTimestamp values
			continue
		}
		m[f.Name] = val
	}
	var pv *pb.Value
	if len(m) == 0 && sawTransform {
		// The entire struct consisted of ServerTimestamp or omitempty values.
		pv = nil
	} else {
		pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
	}
	return pv, sawTransform, nil
}

type tagOptions struct {
	omitEmpty       bool // do not marshal value if empty
	serverTimestamp bool // set time.Time to server timestamp on write
}

// parseTag interprets firestore struct field tags.
func parseTag(t reflect.StructTag) (name string, keep bool, other interface{}, err error) {
	name, keep, opts, err := fields.ParseStandardTag("firestore", t)
	if err != nil {
		return "", false, nil, fmt.Errorf("firestore: %v", err)
	}
	tagOpts := tagOptions{}
	for _, opt := range opts {
		switch opt {
		case "omitempty":
			tagOpts.omitEmpty = true
		case "serverTimestamp":
			tagOpts.serverTimestamp = true
		default:
			return "", false, nil, fmt.Errorf("firestore: unknown tag option: %q", opt)
		}
	}
	return name, keep, tagOpts, nil
}

// isLeafType determines whether or not a type is a 'leaf type'
// and should not be recursed into, but considered one field.
func isLeafType(t reflect.Type) bool {
	return t == typeOfGoTime || t == typeOfLatLng || t == typeOfProtoTimestamp
}

var fieldCache = fields.NewCache(parseTag, nil, isLeafType)

// isEmptyValue is taken from the encoding/json package in the
// standard library.
// TODO(jba): move to the fields package
func isEmptyValue(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Ptr:
		return v.IsNil()
	}
	if v.Type() == typeOfGoTime {
		return v.Interface().(time.Time).IsZero()
	}
	return false
}
