// 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 store.WrapError(st.err)
	}
	st.node.Close()
	st.err = verror.New(verror.ErrCanceled, nil, "closed store")
	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, store.WrapError(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}
	}
	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(st store.StoreReadWriter) error {
		return st.Put(key, value)
	})
}

// Delete implements the store.StoreWriter interface.
func (st *memstore) Delete(key []byte) error {
	return store.RunInTransaction(st, func(st store.StoreReadWriter) error {
		return st.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{st.err}
	}
	return newSnapshot(st, st.node)
}
