// 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 localblobstore is the interface to a local blob store.
// Implementations include fs_cablobstore.
//
// Expected use
// ============
// These examples assume that bs, bsS (sender) and bsR (receiver) are blobstores.
//
// Writing blobs
//      bw, err := bs.NewBlobWriter(ctx, "")  // For a new blob, implementation picks blob name.
//      if err == nil {
//		blobName := bw.Name()  // Get name the implementation picked.
//   	  	... use bw.AppendFragment() to append data to the blob...
//   	  	... and/or bw.AppendBlob() to append data that's in another existing blob...
//        	err = bw.Close()
//   	}
//
// Resume writing a blob that was partially written due to a crash (not yet finalized).
//	bw, err := bs.ResumeBlobWriter(ctx, name)
//	if err == nil {
//		size := bw.Size() // The store has this many bytes from the blob.
//		... write the remaining data using bwAppendFragment() and/or bw.AppendBlob()...
//		err = bw.Close()
//	}
//
// Reading blobs
//	br, err := bs.NewBlobReader(ctx, name)
//	if err == nil {
//		... read bytes with br.ReadAt() or br.Read(), perhas with br.Seek()...
//		err = br.Close()
//	}
//
// Transferring blobs from one store to another:
// See example in localblobstore_transfer_test.go
// Summary:
// - The sender sends the chunksum of the blob from BlobReader's Hash().
// - The receiver checks whether it already has the blob, with the same
//   checksum.
// - If the receiver does not have the blob, the sender sends the list of chunk
//   hashes in the blob using BlobChunkStream().
// - The receiver uses RecipeStreamFromChunkStream() with the chunk hash stream
//   from the sender, and tells the sender the chunk hashes of the chunks it
//   needs.
// - The sender uses LookupChunk() to find the data for each chunk the receiver
//   needs, and sends it to the receiver.
// - The receiver applies the recipe steps, with the actual chunkj data from
//   the sender and its own local data.
package localblobstore

import "v.io/v23/context"

// A BlobStore represents a simple, content-addressable store.
type BlobStore interface {
	// NewBlobReader() returns a pointer to a newly allocated BlobReader on
	// the specified blobName.  BlobReaders should not be used concurrently
	// by multiple threads.  Returned handles should be closed with
	// Close().
	NewBlobReader(ctx *context.T, blobName string) (br BlobReader, err error)

	// NewBlobWriter() returns a pointer to a newly allocated BlobWriter on
	// a newly created blob.  If "name" is non-empty, its is used to name
	// the blob, and it must be in the format of a name returned by this
	// interface (probably by another instance on another device).
	// Otherwise, otherwise a new name is created, which can be found using
	// the Name() method.  It is an error to attempt to overwrite a blob
	// that already exists in this blob store.  BlobWriters should not be
	// used concurrently by multiple threads.  The returned handle should
	// be closed with either the Close() or CloseWithoutFinalize() method
	// to avoid leaking file handles.
	NewBlobWriter(ctx *context.T, name string) (bw BlobWriter, err error)

	// ResumeBlobWriter() returns a pointer to a newly allocated BlobWriter on
	// an old, but unfinalized blob name.
	ResumeBlobWriter(ctx *context.T, blobName string) (bw BlobWriter, err error)

	// DeleteBlob() deletes the named blob from the BlobStore.
	DeleteBlob(ctx *context.T, blobName string) (err error)

	// GC() removes old temp files and content-addressed blocks that are no
	// longer referenced by any blob.  It may be called concurrently with
	// other calls to GC(), and with uses of BlobReaders and BlobWriters.
	GC(ctx *context.T) error

	// BlobChunkStream() returns a ChunkStream that can be used to read the
	// ordered list of content hashes of chunks in blob blobName.  It is
	// expected that this list will be presented to
	// RecipeStreamFromChunkStream() on another device, to create a recipe
	// for transmitting the blob efficiently to that other device.
	BlobChunkStream(ctx *context.T, blobName string) ChunkStream

	// RecipeStreamFromChunkStream() returns a pointer to a RecipeStream
	// that allows the client to iterate over each RecipeStep needed to
	// create the blob formed by the chunks in chunkStream.  It is expected
	// that this will be called on a receiving device, and be given a
	// ChunkStream from a sending device, to yield a recipe for efficient
	// chunk transfer.  RecipeStep values with non-nil Chunk fields need
	// the chunk from the sender; once the data is returned it can be
	// written with BlobWriter.AppendFragment().  Those with blob
	// references can be written locally with BlobWriter.AppendBlob().
	RecipeStreamFromChunkStream(ctx *context.T, chunkStream ChunkStream) RecipeStream

	// LookupChunk() returns the location of a chunk with the specified chunk
	// hash within the store.  It is expected that chunk hashes from
	// RecipeStep entries from RecipeStreamFromChunkStream() will be mapped
	// to blob Location values on the sender for transmission to the
	// receiver.
	LookupChunk(ctx *context.T, chunkHash []byte) (loc Location, err error)

	// ListBlobIds() returns an iterator that can be used to enumerate the
	// blobs in a BlobStore.  Expected use is:
	//
	//	iter := bs.ListBlobIds(ctx)
	//	for iter.Advance() {
	//	  // Process iter.Value() here.
	//	}
	//	if iter.Err() != nil {
	//	  // The loop terminated early due to an error.
	//	}
	ListBlobIds(ctx *context.T) (iter Stream)

	// ListCAIds() returns an iterator that can be used to enumerate the
	// content-addressable fragments in a BlobStore.  Expected use is:
	//
	//	iter := bs.ListCAIds(ctx)
	//	for iter.Advance() {
	//	  // Process iter.Value() here.
	//	}
	//	if iter.Err() != nil {
	//	  // The loop terminated early due to an error.
	//	}
	ListCAIds(ctx *context.T) (iter Stream)

	// Root() returns the name of the root directory where the BlobStore is stored.
	Root() string

	// Close() closes the BlobStore.
	Close() error
}

// A Location describes chunk's location within a blob.  It is returned by
// BlobStore.LookupChunk().
type Location struct {
	BlobName string // name of blob
	Offset   int64  // byte offset of chunk within blob
	Size     int64  // size of chunk
}

// A BlobReader allows a blob to be read using the standard ReadAt(), Read(),
// and Seek() calls.  A BlobReader can be created with NewBlobReader(), and
// should be closed with the Close() method to avoid leaking file handles.
type BlobReader interface {
	// ReadAt() fills b[] with up to len(b) bytes of data starting at
	// position "at" within the blob that the BlobReader indicates, and
	// returns the number of bytes read.
	ReadAt(b []byte, at int64) (n int, err error)

	// Read() fills b[] with up to len(b) bytes of data starting at the
	// current seek position of the BlobReader within the blob that the
	// BlobReader indicates, and then both returns the number of bytes read
	// and advances the BlobReader's seek position by that amount.
	Read(b []byte) (n int, err error)

	// Seek() sets the seek position of the BlobReader to offset if
	// whence==0, offset+current_seek_position if whence==1, and
	// offset+end_of_blob if whence==2, and then returns the current seek
	// position.
	Seek(offset int64, whence int) (result int64, err error)

	// Close() indicates that the client will perform no further operations
	// on the BlobReader.  It releases any resources held by the
	// BlobReader.
	Close() error

	// Name() returns the BlobReader's name.
	Name() string

	// Size() returns the BlobReader's size.
	Size() int64

	// IsFinalized() returns whether the BlobReader has been finalized.
	IsFinalized() bool

	// Hash() returns the BlobReader's hash.  It may be nil if the blob is
	// not finalized.
	Hash() []byte
}

// A BlockOrFile represents a vector of bytes, and contains either a data
// block (as a []byte), or a (file name, size, offset) triple.
type BlockOrFile struct {
	Block    []byte // If FileName is empty, the bytes represented.
	FileName string // If non-empty, the name of the file containing the bytes.
	Size     int64  // If FileName is non-empty, the number of bytes (or -1 for "all")
	Offset   int64  // If FileName is non-empty, the offset of the relevant bytes within the file.
}

// A BlobWriter allows a blob to be written.  If a blob has not yet been
// finalized, it also allows that blob to be extended.  A BlobWriter may be
// created with NewBlobWriter(), and should be closed with Close() or
// CloseWithoutFinalize().
type BlobWriter interface {
	// AppendBlob() adds a (substring of a) pre-existing blob to the blob
	// being written by the BlobWriter.  The fragments of the pre-existing
	// blob are not physically copied; they are referenced by both blobs.
	AppendBlob(blobName string, size int64, offset int64) (err error)

	// AppendFragment() appends a fragment to the blob being written by the
	// BlobWriter, where the fragment is composed of the byte vectors
	// described by the elements of item[].  The fragment is copied into
	// the blob store.
	AppendFragment(item ...BlockOrFile) (err error)

	// Close() finalizes the BlobWriter, and indicates that the client will
	// perform no further append operations on the BlobWriter.  Any
	// internal open file handles are closed.
	Close() (err error)

	// CloseWithoutFinalize() indicates that the client will perform no
	// further append operations on the BlobWriter, but does not finalize
	// the blob.  Any internal open file handles are closed.  Clients are
	// expected to need this operation infrequently.
	CloseWithoutFinalize() (err error)

	// Name() returns the BlobWriter's name.
	Name() string

	// Size() returns the BlobWriter's size.
	Size() int64

	// IsFinalized() returns whether the BlobWriter has been finalized.
	IsFinalized() bool

	// Hash() returns the BlobWriter's hash, reflecting the bytes written so far.
	Hash() []byte
}

// A Stream represents an iterator that allows the client to enumerate
// all the blobs or fragments in a BlobStore.
//
// The interfaces Stream, ChunkStream, RecipeStream all have four calls,
// and differ only in the Value() call.
type Stream interface {
	// Advance() stages an item so that it may be retrieved via Value().
	// Returns true iff there is an item to retrieve.  Advance() must be
	// called before Value() is called.  The caller is expected to read
	// until Advance() returns false, or to call Cancel().
	Advance() bool

	// Value() returns the item that was staged by Advance().  May panic if
	// Advance() returned false or was not called.  Never blocks.
	Value() (name string)

	// Err() returns any error encountered by Advance.  Never blocks.
	Err() error

	// Cancel() indicates that the client wishes to cease reading from the stream.
	// It causes the next call to Advance() to return false.  Never blocks.
	// It may be called concurrently with other calls on the stream.
	Cancel()
}

// A ChunkStream represents an iterator that allows the client to enumerate
// the chunks in a blob.   See the comments for Stream for usage.
type ChunkStream interface {
	Advance() bool

	// Value() returns the chunkHash that was staged by Advance().  May
	// panic if Advance() returned false or was not called.  Never blocks.
	// The result may share storage with buf[] if it is large enough;
	// otherwise, a new buffer is allocated.  It is legal to call with
	// buf==nil.
	Value(buf []byte) (chunkHash []byte)

	Err() error
	Cancel()
}

// A RecipeStep describes one piece of a recipe for making a blob.
// The step consists either of appending the chunk with content hash Chunk and size Size,
// or (if Chunk==nil) the Size bytes from Blob, starting at Offset.
type RecipeStep struct {
	Chunk  []byte
	Blob   string
	Size   int64
	Offset int64
}

// A RecipeStream represents an iterator that allows the client to obtain the
// steps needed to construct a blob with a given ChunkStream, attempting to
// reuse data in existing blobs.  See the comments for Stream for usage.
type RecipeStream interface {
	Advance() bool

	// Value() returns the RecipeStep that was staged by Advance().  May panic if
	// Advance() returned false or was not called.  Never blocks.
	Value() RecipeStep

	Err() error
	Cancel()
}
