// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package nosql defines the wire API for the NoSQL part of Syncbase.
package nosql

import (
	"v.io/v23/security/access"
	"v.io/v23/services/permissions"
)

// Database represents a collection of Tables. Batches, queries, sync, watch,
// etc. all operate at the Database level.
// Database.Glob operates over Table names.
//
// TODO(sadovsky): Add Watch method.
type Database interface {
	// Create creates this Database.
	// If perms is nil, we inherit (copy) the App perms.
	// Create requires the caller to have Write permission at the App.
	Create(perms access.Permissions, metadata ?SchemaMetadata) error {access.Write}

	// Delete deletes this Database.
	Delete() error {access.Write}

	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists() (bool | error) {access.Read}

	// BeginBatch creates a new batch. It returns an App-relative name for a
	// Database handle bound to this batch. If this Database is already bound to a
	// batch, BeginBatch() will fail with ErrBoundToBatch. Concurrency semantics
	// are documented in model.go.
	// TODO(sadovsky): make BatchOptions optional
	BeginBatch(bo BatchOptions) (string | error) {access.Read}

	// Commit persists the pending changes to the database.
	// If this Database is not bound to a batch, Commit() will fail with
	// ErrNotBoundToBatch.
	Commit() error {access.Read}

	// Exec executes a syncQL query and returns all results as specified by in the
	// query's select clause. Concurrency semantics are documented in model.go.
	Exec(query string) stream<_, []any> error {access.Read}

	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If this Database is not bound to a batch, Abort() will fail with
	// ErrNotBoundToBatch.
	Abort() error {access.Read}

	// SetPermissions and GetPermissions are included from the Object interface.
	permissions.Object

	// DatabaseWatcher implements the API to watch for updates in the database.
	DatabaseWatcher

	// SyncGroupManager implements the API for managing SyncGroups attached to a
	// Database.
	SyncGroupManager

	// BlobManager implements the API for managing blobs attached to rows in
	// a Database.
	BlobManager

	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManager
}

// Table represents a collection of Rows.
// Table.Glob operates over the primary keys of Rows in the Table.
type Table interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(perms access.Permissions) error {access.Write}

	// Delete deletes this Table.
	Delete() error {access.Write}

	// Exists returns true only if this Table exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists() (bool | error) {access.Read}

	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	DeleteRowRange(start, limit []byte) error {access.Write}

	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included. Concurrency semantics are
	// documented in model.go.
	Scan(start, limit []byte) stream<_, KeyValue> error {access.Read}

	// GetPermissions returns an array of (prefix, perms) pairs. The array is
	// sorted from longest prefix to shortest, so element zero is the one that
	// applies to the row with the given key. The last element is always the
	// prefix "" which represents the table's permissions -- the array will always
	// have at least one element.
	GetPermissions(key string) ([]PrefixPermissions | error) {access.Admin}

	// SetPermissions sets the permissions for all current and future rows with
	// the given prefix. If the prefix overlaps with an existing prefix, the
	// longest prefix that matches a row applies. For example:
	//     SetPermissions(ctx, Prefix("a/b"), perms1)
	//     SetPermissions(ctx, Prefix("a/b/c"), perms2)
	// The permissions for row "a/b/1" are perms1, and the permissions for row
	// "a/b/c/1" are perms2.
	SetPermissions(prefix string, perms access.Permissions) error {access.Admin}

	// DeletePermissions deletes the permissions for the specified prefix. Any
	// rows covered by this prefix will use the next longest prefix's permissions
	// (see the array returned by GetPermissions).
	DeletePermissions(prefix string) error {access.Admin}
}

// Row represents a single row in a Table.
// All access checks are performed against the most specific matching prefix
// permissions in the Table.
// NOTE(sadovsky): Currently we send []byte values over the wire for Get, Put,
// and Scan. If there's a way to avoid encoding/decoding on the server side, we
// can use vdl.Value everywhere without sacrificing performance.
type Row interface {
	// Exists returns true only if this Row exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists() (bool | error) {access.Read}

	// Get returns the value for this Row.
	Get() ([]byte | error) {access.Read}

	// Put writes the given value for this Row.
	Put(value []byte) error {access.Write}

	// Delete deletes this Row.
	Delete() error {access.Write}
}

// SyncGroupManager is the interface for SyncGroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncGroupManager interface {
	// GetSyncGroupNames returns the global names of all SyncGroups attached to
	// this database.
	GetSyncGroupNames() ([]string | error) {access.Read}

	// CreateSyncGroup creates a new SyncGroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; prefix ACL
	// must exist at each SyncGroup prefix; Client must have at least Read access
	// on each of these prefix ACLs.
	CreateSyncGroup(sgName string, spec SyncGroupSpec, myInfo SyncGroupMemberInfo) error {access.Read}

	// JoinSyncGroup joins the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	JoinSyncGroup(sgName string, myInfo SyncGroupMemberInfo) (spec SyncGroupSpec | error) {access.Read}

	// LeaveSyncGroup leaves the SyncGroup. Previously synced data will continue
	// to be available.
	//
	// Requires: Client must have at least Read access on the Database.
	LeaveSyncGroup(sgName string) error {access.Read}

	// DestroySyncGroup destroys the SyncGroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	DestroySyncGroup(sgName string) error {access.Read}

	// EjectFromSyncGroup ejects a member from the SyncGroup. The ejected member
	// will not be able to sync further, but will retain any data it has already
	// synced.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	EjectFromSyncGroup(sgName, member string) error {access.Read}

	// GetSyncGroupSpec gets the SyncGroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncGroupSpec.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupSpec(sgName string) (spec SyncGroupSpec, version string | error) {access.Read}

	// SetSyncGroupSpec sets the SyncGroup spec. version may be either empty or
	// the value from a previous Get. If not empty, Set will only succeed if the
	// current version matches the specified one.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	SetSyncGroupSpec(sgName string, spec SyncGroupSpec, version string) error {access.Read}

	// GetSyncGroupMembers gets the info objects for members of the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupMembers(sgName string) (members map[string]SyncGroupMemberInfo | error) {access.Read}

	// TODO(hpucha): Add support for client-side conflict resolution and sync
	// policies.
	// StartConflictResolution(name string) stream<ResolutionInfo, ConflictInfo> error
	// Suspend/ResumeSync
	// Get/SetSyncPolicy with policies such as "sync only via wifi", "sync
	// aggressively", "sync once per day".
}

// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManager interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Client must have at least Read access on the Database.
	GetSchemaMetadata() (SchemaMetadata | error) {access.Read}

	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Client must have at least Write access on the Database.
	SetSchemaMetadata(metadata SchemaMetadata) error {access.Write}
}

// BlobManager is the interface for blob operations.
type BlobManager interface {
	// API for resumable blob creation (append-only). After commit, a blob
	// is immutable. Before commit, the BlobRef can be used with PutBlob,
	// GetBlobSize, DeleteBlob, and CommitBlob.
	//
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob() (br BlobRef | error) {access.Write}

	// PutBlob appends the byte stream to the blob.
	PutBlob(br BlobRef) stream<[]byte, _> error {access.Write}

	// CommitBlob marks the blob as immutable.
	CommitBlob(br BlobRef) error {access.Write}

	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(br BlobRef) (uint64 | error) {access.Read}

	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(br BlobRef) error {access.Write}

	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(br BlobRef, offset uint64) stream<_, []byte> error {access.Read}

	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(br BlobRef, priority uint64) stream<_, FetchStatus> error {access.Read}

	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(br BlobRef) error {access.Write}

	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(br BlobRef) error {access.Write}

	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(br BlobRef, rank uint64) error {access.Write}

	// TODO(hpucha): Add API for efficient blob cloning. Options include:
	// (1) CloneBlob RPC with an array of mods that sepcify the offset and
	// len for the new bytes. This might need two len fields to support
	// growing a blob in the middle instead of just replacing byte for byte
	// in the src blob. Or perhaps Offset>=0 to mean "read from old blob at
	// this offset for Length bytes", and Offset<0 to mean "read the next
	// Length Bytes from the PutBlob() stream". (2) We could adopt API
	// similar to the local blob store with BlockOrFile segments, giving a
	// more flexible way to clone blobs. Also provide support for parallel
	// blob upload.
}

// Watch allows a client to watch for updates in the database. For each watched
// request, the client will receive a reliable stream of watch events without
// re-ordering.
//
// The watching is done by starting a streaming RPC. The argument to the RPC
// contains the ResumeMarker that points to a particular place in the database
// event log and a set of (table, row prefix) pairs. Updates with rows not
// covered by the set are excluded from the result stream. The result stream
// consists of a never-ending sequence of Change messages (until the call fails
// or is canceled). Each Change message contains an optional continued bit.
// A sub-sequence of Change messages with continued=true followed by a Change
// message with continued=false forms a batch. If the client has no access to
// a row specified in a change, that change is excluded from the result stream.
//
// See "v.io/v23/services/watch".GlobWatcher for more detailed explanation of
// the general behavior.
//
// The DatabaseWatcher is designed to be used in the following way:
// 1) begin a read-only batch
// 2) read all information your app needs
// 3) read the ResumeMarker
// 4) abort the batch
// 5) start watching changes to the data using the ResumeMarker
// In this configuration the client doesn't miss any changes.
type DatabaseWatcher interface {
	// Watch returns a stream of changes for a given watch request. If this
	// Database is bound to a batch, Watch() will fail with ErrBoundToBatch.
	// If the provided ResumeMarker is invalid or outdated, Watch() will fail
	// with "v.io/v23/services/watch".ErrUnknownResumeMarker.
	Watch(req WatchRequest) stream<_, Change> error {access.Read}

	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the current event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker() (ResumeMarker | error) {access.Read}
}

error (
	BoundToBatch() {"en": "bound to batch"}
	NotBoundToBatch() {"en": "not bound to batch"}
	ReadOnlyBatch() {"en": "batch is read-only"}
)
