// 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.
func toProtoValue(v reflect.Value) (pbv *pb.Value, sawServerTimestamp 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())
	}
}

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, sawServerTimestamp, err := toProtoValue(v.Index(i))
		if err != nil {
			return nil, false, err
		}
		if sawServerTimestamp {
			return nil, false, errors.New("firestore: ServerTimestamp cannot occur in an array")
		}
		vals[i] = val
	}
	return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: vals}}}, false, nil
}

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{}
	sawServerTimestamp := false
	for _, k := range v.MapKeys() {
		mi := v.MapIndex(k)
		if mi.Interface() == ServerTimestamp {
			sawServerTimestamp = true
			continue
		}
		val, sst, err := toProtoValue(mi)
		if err != nil {
			return nil, false, err
		}
		if sst {
			sawServerTimestamp = 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 && sawServerTimestamp {
		// The entire map consisted of ServerTimestamp values.
		pv = nil
	} else {
		pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
	}
	return pv, sawServerTimestamp, nil
}

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
	}
	sawServerTimestamp := false
	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?
			sawServerTimestamp = true
			continue
		}
		if opts.omitEmpty && isEmptyValue(fv) {
			continue
		}
		val, sst, err := toProtoValue(fv)
		if err != nil {
			return nil, false, err
		}
		if sst {
			sawServerTimestamp = 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 && sawServerTimestamp {
		// 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, sawServerTimestamp, 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
}
