// 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 (
	"fmt"
	"sync"

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

type memstore struct {
	mu   sync.Mutex
	node *store.ResourceNode
	data map[string][]byte
	err  error
}

// New creates a new memstore.
func New() store.Store {
	return transactions.Wrap(&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.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, store.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{Error: st.err}
	}
	// TODO(sadovsky): Close snapshot once stream is closed or canceled.
	return newSnapshot(st, st.node).Scan(start, limit)
}

// 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)
}

// WriteBatch implements the transactions.BatchStore interface.
func (st *memstore) WriteBatch(batch ...transactions.WriteOp) error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return store.ConvertError(st.err)
	}
	for _, write := range batch {
		switch write.T {
		case transactions.PutOp:
			st.data[string(write.Key)] = write.Value
		case transactions.DeleteOp:
			delete(st.data, string(write.Key))
		default:
			panic(fmt.Sprintf("unknown write operation type: %v", write.T))
		}
	}
	return nil
}
