// 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 mem provides a simple, in-memory implementation of
// server.Store. Since it's a prototype implementation, it doesn't
// bother with entry-level locking.
package mem

import (
	"strconv"
	"sync"

	"v.io/v23/vdl"
	"v.io/v23/verror"
	"v.io/x/ref/services/groups/internal/store"
)

type entry struct {
	Value   interface{}
	Version uint64
}

type memstore struct {
	mu   sync.Mutex
	err  error
	data map[string]*entry
}

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

func New() store.Store {
	return &memstore{data: map[string]*entry{}}
}

func (st *memstore) Get(k string, v interface{}) (version string, err error) {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return "", convertError(st.err)
	}
	e, ok := st.data[k]
	if !ok {
		return "", verror.New(store.ErrUnknownKey, nil, k)
	}
	if err := vdl.Convert(v, e.Value); err != nil {
		return "", convertError(err)
	}
	return strconv.FormatUint(e.Version, 10), nil
}

func (st *memstore) Insert(k string, v interface{}) error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return convertError(st.err)
	}
	if _, ok := st.data[k]; ok {
		return verror.New(store.ErrKeyExists, nil, k)
	}
	st.data[k] = &entry{Value: v}
	return nil
}

func (st *memstore) Update(k string, v interface{}, version string) error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return convertError(st.err)
	}
	e, ok := st.data[k]
	if !ok {
		return verror.New(store.ErrUnknownKey, nil, k)
	}
	if err := e.checkVersion(version); err != nil {
		return err
	}
	st.data[k] = &entry{Value: v, Version: e.Version + 1}
	return nil
}

func (st *memstore) Delete(k string, version string) error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return convertError(st.err)
	}
	e, ok := st.data[k]
	if !ok {
		return verror.New(store.ErrUnknownKey, nil, k)
	}
	if err := e.checkVersion(version); err != nil {
		return err
	}
	delete(st.data, k)
	return nil
}

func (st *memstore) Close() error {
	st.mu.Lock()
	defer st.mu.Unlock()
	if st.err != nil {
		return convertError(st.err)
	}
	st.err = verror.New(verror.ErrCanceled, nil, "closed store")
	return nil
}

////////////////////////////////////////
// Internal helpers

func (e *entry) checkVersion(version string) error {
	newVersion := strconv.FormatUint(e.Version, 10)
	if version != newVersion {
		return verror.NewErrBadVersion(nil)
	}
	return nil
}

func convertError(err error) error {
	return verror.Convert(verror.IDAction{}, nil, err)
}
