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

// This file defines methods for consistently destroying unreferenced database
// stores by using a garbage collection log keeping dbInfos for inactive (not
// fully created or deleted) databases.

import (
	"fmt"

	"v.io/v23/context"
	wire "v.io/v23/services/syncbase"
	"v.io/v23/verror"
	"v.io/v23/vom"
	"v.io/x/lib/vlog"
	"v.io/x/ref/services/syncbase/common"
	"v.io/x/ref/services/syncbase/store"
	storeutil "v.io/x/ref/services/syncbase/store/util"
)

func dbGCKey(path string) string {
	return common.JoinKeyParts(common.DbGCPrefix, path)
}

// putDbGCEntry puts a dbInfo into the garbage collection log. It should be
// used before creating a new database and when marking a database for
// destruction (deleting the dbInfo from active databases).
func putDbGCEntry(ctx *context.T, stw store.StoreWriter, dbInfo *DbInfo) error {
	return store.Put(ctx, stw, dbGCKey(dbInfo.RootDir), dbInfo)
}

// delDbGCEntry removes a dbInfo from the garbage collection log. It should
// be used after successfully destroying the database and when finalizing
// database creation (putting the dbInfo into active databases).
func delDbGCEntry(ctx *context.T, stw store.StoreWriter, dbInfo *DbInfo) error {
	return store.Delete(ctx, stw, dbGCKey(dbInfo.RootDir))
}

// deleteDatabaseEntry marks a database for destruction by moving its dbInfo
// record from active databases into the garbage collection log. It returns
// the dbInfo that can be passed to finalizeDatabaseDestroy.
func deleteDatabaseEntry(ctx *context.T, tx store.Transaction, dbId wire.Id) (*DbInfo, error) {
	dbInfo, err := getDbInfo(ctx, tx, dbId)
	if err != nil {
		return nil, err
	}
	if err := putDbGCEntry(ctx, tx, dbInfo); err != nil {
		return nil, err
	}
	if err := delDbInfo(ctx, tx, dbId); err != nil {
		return nil, err
	}
	return dbInfo, nil
}

// finalizeDatabaseDestroy attempts to close (if stRef is not nil) and destroy
// the database store. If successful, it removes the dbInfo record from the
// garbage collection log.
func finalizeDatabaseDestroy(ctx *context.T, stw store.StoreWriter, dbInfo *DbInfo, stRef store.Store) error {
	vlog.VI(2).Infof("server: destroying store at %q for database %v (closing: %v)", dbInfo.RootDir, dbInfo.Id, stRef != nil)
	if stRef != nil {
		// TODO(ivanpi): Safer to crash syncbased on Close() failure? Otherwise,
		// already running calls might continue using the database. Alternatively,
		// explicitly cancel running calls in Destroy.
		if err := stRef.Close(); err != nil {
			return wrapGCError(dbInfo, err)
		}
	}
	if err := storeutil.DestroyStore(dbInfo.Engine, dbInfo.RootDir); err != nil {
		return wrapGCError(dbInfo, err)
	}
	if err := delDbGCEntry(ctx, stw, dbInfo); err != nil {
		return wrapGCError(dbInfo, err)
	}
	return nil
}

// runGCInactiveDatabases iterates over the garbage collection log, attempting
// to destroy each database store, removing dbInfo records from the log when
// destruction is successful.
// NOTE: runGCInactiveDatabases should not be run in parallel with database
// creation or deletion since it can cause spurious failures (e.g. garbage
// collecting a database that is being created).
// TODO(ivanpi): Consider adding mutex to allow running GC concurrently.
func runGCInactiveDatabases(ctx *context.T, st store.Store) error {
	vlog.VI(2).Infof("server: starting garbage collection of inactive databases")
	total := 0
	deleted := 0
	gcIt := st.Scan(common.ScanPrefixArgs(common.DbGCPrefix, ""))
	var diBytes []byte
	for gcIt.Advance() {
		diBytes = gcIt.Value(diBytes)
		var dbInfo DbInfo
		if err := vom.Decode(diBytes, &dbInfo); err != nil {
			verror.New(verror.ErrInternal, ctx, err)
		}
		total++
		if err := finalizeDatabaseDestroy(ctx, st, &dbInfo, nil); err != nil {
			vlog.Error(err)
		} else {
			deleted++
		}
	}
	if err := gcIt.Err(); err != nil {
		return verror.New(verror.ErrInternal, ctx, err)
	}
	vlog.VI(2).Infof("server: garbage collected %d out of %d inactive databases", deleted, total)
	return nil
}

func wrapGCError(dbInfo *DbInfo, err error) error {
	return fmt.Errorf("failed to destroy store at %q for database %v: %v", dbInfo.RootDir, dbInfo.Id, err)
}
