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

	pb "cloud.google.com/go/firestore/apiv1/firestorepb"
	"github.com/golang/protobuf/ptypes"
	tspb "github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// A DocumentSnapshot contains document data and metadata.
type DocumentSnapshot struct {
	// The DocumentRef for this document.
	Ref *DocumentRef

	// Read-only. The time at which the document was created.
	// Increases monotonically when a document is deleted then
	// recreated. It can also be compared to values from other documents and
	// the read time of a query.
	CreateTime time.Time

	// Read-only. The time at which the document was last changed. This value
	// is initially set to CreateTime then increases monotonically with each
	// change to the document. It can also be compared to values from other
	// documents and the read time of a query.
	UpdateTime time.Time

	// Read-only. The time at which the document was read.
	ReadTime time.Time

	c     *Client
	proto *pb.Document
}

// Exists reports whether the DocumentSnapshot represents an existing document.
// Even if Exists returns false, the Ref and ReadTime fields of the DocumentSnapshot
// are valid.
func (d *DocumentSnapshot) Exists() bool {
	return d.proto != nil
}

// Data returns the DocumentSnapshot's fields as a map.
// It is equivalent to
//
//	var m map[string]interface{}
//	d.DataTo(&m)
//
// except that it returns nil if the document does not exist.
func (d *DocumentSnapshot) Data() map[string]interface{} {
	if !d.Exists() {
		return nil
	}
	m, err := createMapFromValueMap(d.proto.Fields, d.c)
	// Any error here is a bug in the client.
	if err != nil {
		panic(fmt.Sprintf("firestore: %v", err))
	}
	return m
}

// DataTo uses the document's fields to populate p, which can be a pointer to a
// map[string]interface{} or a pointer to a struct.
//
// Firestore field values are converted to Go values as follows:
//   - Null converts to nil.
//   - Bool converts to bool.
//   - String converts to string.
//   - Integer converts int64. When setting a struct field, any signed or unsigned
//     integer type is permitted except uint, uint64 or uintptr. Overflow is detected
//     and results in an error.
//   - Double converts to float64. When setting a struct field, float32 is permitted.
//     Overflow is detected and results in an error.
//   - Bytes is converted to []byte.
//   - Timestamp converts to time.Time.
//   - GeoPoint converts to *latlng.LatLng, where latlng is the package
//     "google.golang.org/genproto/googleapis/type/latlng".
//   - Arrays convert to []interface{}. When setting a struct field, the field
//     may be a slice or array of any type and is populated recursively.
//     Slices are resized to the incoming value's size, while arrays that are too
//     long have excess elements filled with zero values. If the array is too short,
//     excess incoming values will be dropped.
//   - Maps convert to map[string]interface{}. When setting a struct field,
//     maps of key type string and any value type are permitted, and are populated
//     recursively.
//   - References are converted to *firestore.DocumentRefs.
//
// Field names given by struct field tags are observed, as described in
// DocumentRef.Create.
//
// Only the fields actually present in the document are used to populate p. Other fields
// of p are left unchanged.
//
// If the document does not exist, DataTo returns a NotFound error.
func (d *DocumentSnapshot) DataTo(p interface{}) error {
	if !d.Exists() {
		return status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path)
	}
	return setFromProtoValue(p, &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: d.proto.Fields}}}, d.c)
}

// DataAt returns the data value denoted by path.
//
// The path argument can be a single field or a dot-separated sequence of
// fields, and must not contain any of the runes "˜*/[]". Use DataAtPath instead for
// such a path.
//
// See DocumentSnapshot.DataTo for how Firestore values are converted to Go values.
//
// If the document does not exist, DataAt returns a NotFound error.
func (d *DocumentSnapshot) DataAt(path string) (interface{}, error) {
	if !d.Exists() {
		return nil, status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path)
	}
	fp, err := parseDotSeparatedString(path)
	if err != nil {
		return nil, err
	}
	return d.DataAtPath(fp)
}

// DataAtPath returns the data value denoted by the FieldPath fp.
// If the document does not exist, DataAtPath returns a NotFound error.
func (d *DocumentSnapshot) DataAtPath(fp FieldPath) (interface{}, error) {
	if !d.Exists() {
		return nil, status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path)
	}
	v, err := valueAtPath(fp, d.proto.Fields)
	if err != nil {
		return nil, err
	}
	return createFromProtoValue(v, d.c)
}

// valueAtPath returns the value of m referred to by fp.
func valueAtPath(fp FieldPath, m map[string]*pb.Value) (*pb.Value, error) {
	for _, k := range fp[:len(fp)-1] {
		v := m[k]
		if v == nil {
			return nil, fmt.Errorf("firestore: no field %q", k)
		}
		mv := v.GetMapValue()
		if mv == nil {
			return nil, fmt.Errorf("firestore: value for field %q is not a map", k)
		}
		m = mv.Fields
	}
	k := fp[len(fp)-1]
	v := m[k]
	if v == nil {
		return nil, fmt.Errorf("firestore: no field %q", k)
	}
	return v, nil
}

// toProtoDocument converts a Go value to a Document proto.
// Valid values are: map[string]T, struct, or pointer to a valid value.
// It also returns a list DocumentTransforms.
func toProtoDocument(x interface{}) (*pb.Document, []*pb.DocumentTransform_FieldTransform, error) {
	if x == nil {
		return nil, nil, errors.New("firestore: nil document contents")
	}
	v := reflect.ValueOf(x)
	pv, _, err := toProtoValue(v)
	if err != nil {
		return nil, nil, err
	}
	var transforms []*pb.DocumentTransform_FieldTransform
	transforms, err = extractTransforms(v, nil)
	if err != nil {
		return nil, nil, err
	}
	var fields map[string]*pb.Value
	if pv != nil {
		m := pv.GetMapValue()
		if m == nil {
			return nil, nil, fmt.Errorf("firestore: cannot convert value of type %T into a map", x)
		}
		fields = m.Fields
	}
	return &pb.Document{Fields: fields}, transforms, nil
}

func extractTransforms(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) {
	switch v.Kind() {
	case reflect.Map:
		return extractTransformsFromMap(v, prefix)
	case reflect.Struct:
		return extractTransformsFromStruct(v, prefix)
	case reflect.Ptr:
		if v.IsNil() {
			return nil, nil
		}
		return extractTransforms(v.Elem(), prefix)
	case reflect.Interface:
		if v.NumMethod() == 0 { // empty interface: recurse on its contents
			return extractTransforms(v.Elem(), prefix)
		}
		return nil, nil
	default:
		return nil, nil
	}
}

func extractTransformsFromMap(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) {
	var transforms []*pb.DocumentTransform_FieldTransform
	for _, k := range v.MapKeys() {
		sk := k.Interface().(string) // assume keys are strings; checked in toProtoValue
		path := prefix.with(sk)
		mi := v.MapIndex(k)
		if mi.Interface() == ServerTimestamp {
			transforms = append(transforms, serverTimestamp(path.toServiceFieldPath()))
		} else if au, ok := mi.Interface().(arrayUnion); ok {
			t, err := arrayUnionTransform(au, path)
			if err != nil {
				return nil, err
			}
			transforms = append(transforms, t)
		} else if ar, ok := mi.Interface().(arrayRemove); ok {
			t, err := arrayRemoveTransform(ar, path)
			if err != nil {
				return nil, err
			}
			transforms = append(transforms, t)
		} else if ar, ok := mi.Interface().(transform); ok {
			t, err := fieldTransform(ar, path)
			if err != nil {
				return nil, err
			}
			transforms = append(transforms, t)
		} else {
			ps, err := extractTransforms(mi, path)
			if err != nil {
				return nil, err
			}
			transforms = append(transforms, ps...)
		}
	}
	return transforms, nil
}

func extractTransformsFromStruct(v reflect.Value, prefix FieldPath) ([]*pb.DocumentTransform_FieldTransform, error) {
	var transforms []*pb.DocumentTransform_FieldTransform
	fields, err := fieldCache.Fields(v.Type())
	if err != nil {
		return nil, err
	}
	for _, f := range fields {
		fv := v.FieldByIndex(f.Index)
		path := prefix.with(f.Name)
		opts := f.ParsedTag.(tagOptions)
		if opts.serverTimestamp {
			var isZero bool
			switch f.Type {
			case typeOfGoTime:
				isZero = fv.Interface().(time.Time).IsZero()
			case reflect.PtrTo(typeOfGoTime):
				isZero = fv.IsNil() || fv.Elem().Interface().(time.Time).IsZero()
			default:
				return nil, fmt.Errorf("firestore: field %s of struct %s with serverTimestamp tag must be of type time.Time or *time.Time",
					f.Name, v.Type())
			}
			if isZero {
				transforms = append(transforms, serverTimestamp(path.toServiceFieldPath()))
			}
		} else {
			ps, err := extractTransforms(fv, path)
			if err != nil {
				return nil, err
			}
			transforms = append(transforms, ps...)
		}
	}
	return transforms, nil
}

func newDocumentSnapshot(ref *DocumentRef, proto *pb.Document, c *Client, readTime *tspb.Timestamp) (*DocumentSnapshot, error) {
	d := &DocumentSnapshot{
		Ref:   ref,
		c:     c,
		proto: proto,
	}
	if proto != nil {
		ts, err := ptypes.Timestamp(proto.CreateTime)
		if err != nil {
			return nil, err
		}
		d.CreateTime = ts
		ts, err = ptypes.Timestamp(proto.UpdateTime)
		if err != nil {
			return nil, err
		}
		d.UpdateTime = ts
	}
	if readTime != nil {
		ts, err := ptypes.Timestamp(readTime)
		if err != nil {
			return nil, err
		}
		d.ReadTime = ts
	}
	return d, nil
}

func serverTimestamp(path string) *pb.DocumentTransform_FieldTransform {
	return &pb.DocumentTransform_FieldTransform{
		FieldPath: path,
		TransformType: &pb.DocumentTransform_FieldTransform_SetToServerValue{
			SetToServerValue: pb.DocumentTransform_FieldTransform_REQUEST_TIME,
		},
	}
}
