// 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 memstore provides a simple, in-memory implementation of store.Store.
// Since it's a prototype implementation, it makes no attempt to be performant.
package memstore

import (
	"sync"

	"v.io/syncbase/x/ref/services/syncbase/store"
	"v.io/v23/verror"
)

type memstore struct {
	mu   sync.Mutex
	node *store.ResourceNode
	data map[string][]byte
	err  error
	// Most recent sequence number handed out.
	lastSeq uint64
	// Value of lastSeq at the time of the most recent commit.
	lastCommitSeq uint64
}

var _ store.Store = (*memstore)(nil)

// New creates a new memstore.
func New() store.Store {
	return &memstore{
		data: map[string][]byte{},
		node: store.NewResourceNode(),
	}
}

// Close implements the store.Store interface.
func (st *memstore) Close() error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return convertError(st.err)
	}
	st.node.Close()
	st.err = verror.New(verror.ErrCanceled, nil, store.ErrMsgClosedStore)
	return nil
}

// Get implements the store.StoreReader interface.
func (st *memstore) Get(key, valbuf []byte) ([]byte, error) {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return valbuf, convertError(st.err)
	}
	value, ok := st.data[string(key)]
	if !ok {
		return valbuf, verror.New(store.ErrUnknownKey, nil, string(key))
	}
	return store.CopyBytes(valbuf, value), nil
}

// Scan implements the store.StoreReader interface.
func (st *memstore) Scan(start, limit []byte) store.Stream {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return &store.InvalidStream{st.err}
	}
	// TODO(sadovsky): Close snapshot once stream is closed or canceled.
	return newSnapshot(st, st.node).Scan(start, limit)
}

// Put implements the store.StoreWriter interface.
func (st *memstore) Put(key, value []byte) error {
	return store.RunInTransaction(st, func(tx store.Transaction) error {
		return tx.Put(key, value)
	})
}

// Delete implements the store.StoreWriter interface.
func (st *memstore) Delete(key []byte) error {
	return store.RunInTransaction(st, func(tx store.Transaction) error {
		return tx.Delete(key)
	})
}

// NewTransaction implements the store.Store interface.
func (st *memstore) NewTransaction() store.Transaction {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return &store.InvalidTransaction{st.err}
	}
	st.lastSeq++
	return newTransaction(st, st.node, st.lastSeq)
}

// NewSnapshot implements the store.Store interface.
func (st *memstore) NewSnapshot() store.Snapshot {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return &store.InvalidSnapshot{Error: st.err}
	}
	return newSnapshot(st, st.node)
}
