/*
Copyright 2017 Google Inc. All Rights Reserved.

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 spanner

import (
	"bytes"
	"fmt"
	"time"

	"google.golang.org/grpc/codes"

	"cloud.google.com/go/civil"
	proto3 "github.com/golang/protobuf/ptypes/struct"
	sppb "google.golang.org/genproto/googleapis/spanner/v1"
)

// A Key can be either a Cloud Spanner row's primary key or a secondary index key.
// It is essentially an interface{} array, which represents a set of Cloud Spanner
// columns. A Key type has the following usages:
//
//     - Used as primary key which uniquely identifies a Cloud Spanner row.
//     - Used as secondary index key which maps to a set of Cloud Spanner rows
//       indexed under it.
//     - Used as endpoints of primary key/secondary index ranges,
//       see also the KeyRange type.
//
// Rows that are identified by the Key type are outputs of read operation or targets of
// delete operation in a mutation. Note that for Insert/Update/InsertOrUpdate/Update
// mutation types, although they don't require a primary key explicitly, the column list
// provided must contain enough columns that can comprise a primary key.
//
// Keys are easy to construct.  For example, suppose you have a table with a
// primary key of username and product ID.  To make a key for this table:
//
//	key := spanner.Key{"john", 16}
//
// See the description of Row and Mutation types for how Go types are
// mapped to Cloud Spanner types. For convenience, Key type supports a wide range
// of Go types:
//     - int, int8, int16, int32, int64, and NullInt64 are mapped to Cloud Spanner's INT64 type.
//     - uint8, uint16 and uint32 are also mapped to Cloud Spanner's INT64 type.
//     - float32, float64, NullFloat64 are mapped to Cloud Spanner's FLOAT64 type.
//     - bool and NullBool are mapped to Cloud Spanner's BOOL type.
//     - []byte is mapped to Cloud Spanner's BYTES type.
//     - string and NullString are mapped to Cloud Spanner's STRING type.
//     - time.Time and NullTime are mapped to Cloud Spanner's TIMESTAMP type.
//     - civil.Date and NullDate are mapped to Cloud Spanner's DATE type.
type Key []interface{}

// errInvdKeyPartType returns error for unsupported key part type.
func errInvdKeyPartType(part interface{}) error {
	return spannerErrorf(codes.InvalidArgument, "key part has unsupported type %T", part)
}

// keyPartValue converts a part of the Key (which is a valid Cloud Spanner type)
// into a proto3.Value. Used for encoding Key type into protobuf.
func keyPartValue(part interface{}) (pb *proto3.Value, err error) {
	switch v := part.(type) {
	case int:
		pb, _, err = encodeValue(int64(v))
	case int8:
		pb, _, err = encodeValue(int64(v))
	case int16:
		pb, _, err = encodeValue(int64(v))
	case int32:
		pb, _, err = encodeValue(int64(v))
	case uint8:
		pb, _, err = encodeValue(int64(v))
	case uint16:
		pb, _, err = encodeValue(int64(v))
	case uint32:
		pb, _, err = encodeValue(int64(v))
	case float32:
		pb, _, err = encodeValue(float64(v))
	case int64, float64, NullInt64, NullFloat64, bool, NullBool, []byte, string, NullString, time.Time, civil.Date, NullTime, NullDate:
		pb, _, err = encodeValue(v)
	default:
		return nil, errInvdKeyPartType(v)
	}
	return pb, err
}

// proto converts a spanner.Key into a proto3.ListValue.
func (key Key) proto() (*proto3.ListValue, error) {
	lv := &proto3.ListValue{}
	lv.Values = make([]*proto3.Value, 0, len(key))
	for _, part := range key {
		v, err := keyPartValue(part)
		if err != nil {
			return nil, err
		}
		lv.Values = append(lv.Values, v)
	}
	return lv, nil
}

// String implements fmt.Stringer for Key. For string, []byte and NullString, it
// prints the uninterpreted bytes of their contents, leaving caller with the
// opportunity to escape the output.
func (key Key) String() string {
	b := &bytes.Buffer{}
	fmt.Fprint(b, "(")
	for i, part := range []interface{}(key) {
		if i != 0 {
			fmt.Fprint(b, ",")
		}
		switch v := part.(type) {
		case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool:
			// Use %v to print numeric types and bool.
			fmt.Fprintf(b, "%v", v)
		case string:
			fmt.Fprintf(b, "%q", v)
		case []byte:
			if v != nil {
				fmt.Fprintf(b, "%q", v)
			} else {
				fmt.Fprint(b, "<null>")
			}
		case NullInt64, NullFloat64, NullBool, NullString, NullTime, NullDate:
			// The above types implement fmt.Stringer.
			fmt.Fprintf(b, "%s", v)
		case civil.Date:
			fmt.Fprintf(b, "%q", v)
		case time.Time:
			fmt.Fprintf(b, "%q", v.Format(time.RFC3339Nano))
		default:
			fmt.Fprintf(b, "%v", v)
		}
	}
	fmt.Fprint(b, ")")
	return b.String()
}

// KeyRangeKind describes the kind of interval represented by a KeyRange:
// whether it is open or closed on the left and right.
type KeyRangeKind int

const (
	// ClosedOpen is closed on the left and open on the right: the Start
	// key is included, the End key is excluded.
	ClosedOpen KeyRangeKind = iota

	// ClosedClosed is closed on the left and the right: both keys are included.
	ClosedClosed

	// OpenClosed is open on the left and closed on the right: the Start
	// key is excluded, the End key is included.
	OpenClosed

	// OpenOpen is open on the left and the right: neither key is included.
	OpenOpen
)

// A KeyRange represents a range of rows in a table or index.
//
// A range has a Start key and an End key.  IncludeStart and IncludeEnd
// indicate whether the Start and End keys are included in the range.
//
// For example, consider the following table definition:
//
//	CREATE TABLE UserEvents (
//	  UserName STRING(MAX),
//	  EventDate STRING(10),
//	) PRIMARY KEY(UserName, EventDate);
//
// The following keys name rows in this table:
//
//	spanner.Key{"Bob", "2014-09-23"}
//	spanner.Key{"Alfred", "2015-06-12"}
//
// Since the UserEvents table's PRIMARY KEY clause names two columns, each
// UserEvents key has two elements; the first is the UserName, and the second
// is the EventDate.
//
// Key ranges with multiple components are interpreted lexicographically by
// component using the table or index key's declared sort order. For example,
// the following range returns all events for user "Bob" that occurred in the
// year 2015:
//
// 	spanner.KeyRange{
//		Start: spanner.Key{"Bob", "2015-01-01"},
//		End:   spanner.Key{"Bob", "2015-12-31"},
//		Kind:  ClosedClosed,
//	}
//
// Start and end keys can omit trailing key components. This affects the
// inclusion and exclusion of rows that exactly match the provided key
// components: if IncludeStart is true, then rows that exactly match the
// provided components of the Start key are included; if IncludeStart is false
// then rows that exactly match are not included.  IncludeEnd and End key
// behave in the same fashion.
//
// For example, the following range includes all events for "Bob" that occurred
// during and after the year 2000:
//
//	spanner.KeyRange{
//		Start: spanner.Key{"Bob", "2000-01-01"},
//		End:   spanner.Key{"Bob"},
//		Kind:  ClosedClosed,
//	}
//
// The next example retrieves all events for "Bob":
//
//	spanner.PrefixRange(spanner.Key{"Bob"})
//
// To retrieve events before the year 2000:
//
//	spanner.KeyRange{
//		Start: spanner.Key{"Bob"},
//		End:   spanner.Key{"Bob", "2000-01-01"},
//		Kind:  ClosedOpen,
//	}
//
// Although we specified a Kind for this KeyRange, we didn't need to, because
// the default is ClosedOpen. In later examples we'll omit Kind if it is
// ClosedOpen.
//
// The following range includes all rows in a table or under a
// index:
//
//	spanner.AllKeys()
//
// This range returns all users whose UserName begins with any
// character from A to C:
//
//	spanner.KeyRange{
//		Start: spanner.Key{"A"},
//		End:   spanner.Key{"D"},
//	}
//
// This range returns all users whose UserName begins with B:
//
//	spanner.KeyRange{
//		Start: spanner.Key{"B"},
//		End:   spanner.Key{"C"},
//	}
//
// Key ranges honor column sort order. For example, suppose a table is defined
// as follows:
//
//	CREATE TABLE DescendingSortedTable {
//	  Key INT64,
//	  ...
//	) PRIMARY KEY(Key DESC);
//
// The following range retrieves all rows with key values between 1 and 100
// inclusive:
//
//	spanner.KeyRange{
//		Start: spanner.Key{100},
//		End:   spanner.Key{1},
//		Kind:  ClosedClosed,
//	}
//
// Note that 100 is passed as the start, and 1 is passed as the end, because
// Key is a descending column in the schema.
type KeyRange struct {
	// Start specifies the left boundary of the key range; End specifies
	// the right boundary of the key range.
	Start, End Key

	// Kind describes whether the boundaries of the key range include
	// their keys.
	Kind KeyRangeKind
}

// String implements fmt.Stringer for KeyRange type.
func (r KeyRange) String() string {
	var left, right string
	switch r.Kind {
	case ClosedClosed:
		left, right = "[", "]"
	case ClosedOpen:
		left, right = "[", ")"
	case OpenClosed:
		left, right = "(", "]"
	case OpenOpen:
		left, right = "(", ")"
	default:
		left, right = "?", "?"
	}
	return fmt.Sprintf("%s%s,%s%s", left, r.Start, r.End, right)
}

// proto converts KeyRange into sppb.KeyRange.
func (r KeyRange) proto() (*sppb.KeyRange, error) {
	var err error
	var start, end *proto3.ListValue
	pb := &sppb.KeyRange{}
	if start, err = r.Start.proto(); err != nil {
		return nil, err
	}
	if end, err = r.End.proto(); err != nil {
		return nil, err
	}
	if r.Kind == ClosedClosed || r.Kind == ClosedOpen {
		pb.StartKeyType = &sppb.KeyRange_StartClosed{StartClosed: start}
	} else {
		pb.StartKeyType = &sppb.KeyRange_StartOpen{StartOpen: start}
	}
	if r.Kind == ClosedClosed || r.Kind == OpenClosed {
		pb.EndKeyType = &sppb.KeyRange_EndClosed{EndClosed: end}
	} else {
		pb.EndKeyType = &sppb.KeyRange_EndOpen{EndOpen: end}
	}
	return pb, nil
}
