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