// 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 util

import (
	"os"
	"strconv"

	"v.io/syncbase/x/ref/services/syncbase/store"
	"v.io/syncbase/x/ref/services/syncbase/store/leveldb"
	"v.io/syncbase/x/ref/services/syncbase/store/memstore"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/verror"
	"v.io/v23/vom"
)

func FormatVersion(version uint64) string {
	return strconv.FormatUint(version, 10)
}

func CheckVersion(ctx *context.T, presented string, actual uint64) error {
	if presented != "" && presented != FormatVersion(actual) {
		return verror.NewErrBadVersion(ctx)
	}
	return nil
}

////////////////////////////////////////////////////////////
// RPC-aware, higher-level get/put

type Layer interface {
	// Name returns the name of this instance, e.g. "fooapp" or "bardb".
	Name() string
	// StKey returns the storage engine key to use for metadata about this layer,
	// e.g. "$table:baztable".
	StKey() string
}

type Permser interface {
	// GetPerms returns the Permissions for this Layer.
	GetPerms() access.Permissions
}

// GetWithoutAuth does st.Get(l.StKey(), v), populating v.
// Returns a VDL-compatible error.
func GetWithoutAuth(ctx *context.T, call rpc.ServerCall, st store.StoreReader, l Layer, v interface{}) error {
	if err := GetObject(st, l.StKey(), v); err != nil {
		if verror.ErrorID(err) == store.ErrUnknownKey.ID {
			return verror.New(verror.ErrNoExist, ctx, l.Name())
		}
		return verror.New(verror.ErrInternal, ctx, err)
	}
	return nil
}

// Get does GetWithoutAuth followed by an auth check.
// Returns a VDL-compatible error.
func Get(ctx *context.T, call rpc.ServerCall, st store.StoreReader, l Layer, v Permser) error {
	if err := GetWithoutAuth(ctx, call, st, l, v); err != nil {
		return err
	}
	auth, _ := access.PermissionsAuthorizer(v.GetPerms(), access.TypicalTagType())
	if err := auth.Authorize(ctx, call.Security()); err != nil {
		return verror.New(verror.ErrNoAccess, ctx, l.Name())
	}
	return nil
}

// Put does st.Put(l.StKey(), v).
// Returns a VDL-compatible error.
// If you need to perform an authorization check, use Update().
func Put(ctx *context.T, _ rpc.ServerCall, st store.StoreWriter, l Layer, v interface{}) error {
	if err := PutObject(st, l.StKey(), v); err != nil {
		return verror.New(verror.ErrInternal, ctx, err)
	}
	return nil
}

// Delete does st.Delete(l.StKey()).
// Returns a VDL-compatible error.
// If you need to perform an authorization check, call Get() first.
func Delete(ctx *context.T, _ rpc.ServerCall, st store.StoreWriter, l Layer) error {
	if err := st.Delete([]byte(l.StKey())); err != nil {
		return verror.New(verror.ErrInternal, ctx, err)
	}
	return nil
}

// Update performs a read-modify-write.
// Input v is populated by the "read" step. fn should "modify" v, and should
// return a VDL-compatible error.
// Performs an auth check as part of the "read" step.
// Returns a VDL-compatible error.
func Update(ctx *context.T, call rpc.ServerCall, st store.StoreReadWriter, l Layer, v Permser, fn func() error) error {
	_ = st.(store.Transaction) // panics on failure, as desired
	if err := Get(ctx, call, st, l, v); err != nil {
		return err
	}
	if err := fn(); err != nil {
		return err
	}
	return Put(ctx, call, st, l, v)
}

////////////////////////////////////////////////////////////
// RPC-oblivious, lower-level helpers

func GetObject(st store.StoreReader, k string, v interface{}) error {
	bytes, err := st.Get([]byte(k), nil)
	if err != nil {
		return err
	}
	return vom.Decode(bytes, v)
}

func PutObject(st store.StoreWriter, k string, v interface{}) error {
	bytes, err := vom.Encode(v)
	if err != nil {
		return err
	}
	return st.Put([]byte(k), bytes)
}

func OpenStore(engine, path string) (store.Store, error) {
	switch engine {
	case "memstore":
		return memstore.New(), nil
	case "leveldb":
		if err := os.MkdirAll(path, 0700); err != nil {
			return nil, verror.New(verror.ErrInternal, nil, err)
		}
		return leveldb.Open(path)
	default:
		return nil, verror.New(verror.ErrBadArg, nil, engine)
	}
}

func DestroyStore(engine, path string) error {
	switch engine {
	case "memstore":
		// memstore doesn't persist any data on the disc, do nothing.
		return nil
	case "leveldb":
		if err := os.RemoveAll(path); err != nil {
			return verror.New(verror.ErrInternal, nil, err)
		}
		return nil
	default:
		return verror.New(verror.ErrBadArg, nil, engine)
	}
}
