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

// Utilities for creating and opening the database in Syncbase.
package sbutil

import (
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/syncbase"
	"v.io/v23/syncbase/nosql"
	"v.io/v23/verror"
	"v.io/x/sensorlog_lite/internal/config"
	"v.io/x/sensorlog_lite/internal/sbmodel"
)

// CreateOrOpenDB opens the Sensor Log database hosted on specified Syncbase
// instance, creating it if missing, initializing specified tables.
func CreateOrOpenDB(ctx *context.T, sbService string, tables []sbmodel.TableSpec) (nosql.Database, error) {
	aclFull := access.Permissions{}
	// Allow everyone to resolve to allow joining syncgroups.
	AddPermsForPattern(&aclFull, string(security.AllPrincipals), access.Resolve)
	// Restrict other permissions to self.
	AddPermsForPrincipal(&aclFull, v23.GetPrincipal(ctx), access.Read, access.Write, access.Admin, access.Debug)

	aclReadOnly := access.Permissions{}
	// Allow everyone to resolve to allow joining syncgroups.
	AddPermsForPattern(&aclReadOnly, string(security.AllPrincipals), access.Resolve)
	// Restrict other permissions to self, except Write.
	AddPermsForPrincipal(&aclReadOnly, v23.GetPrincipal(ctx), access.Read, access.Admin, access.Debug)

	sbs := syncbase.NewService(sbService)
	app := sbs.App(config.AppName)
	if err := createIfMissing(ctx, app, aclFull); err != nil {
		return nil, err
	}

	// TODO(ivanpi): Add schema version.
	db := app.NoSQLDatabase(config.DBName, nil)
	if err := createIfMissing(ctx, db, aclFull); err != nil {
		return nil, err
	}

	// TODO(ivanpi): Add table schemas when available.
	for _, ts := range tables {
		tb := db.Table(ts.Prototype.Table())
		acl := aclReadOnly
		if !ts.ReadOnly {
			acl = aclFull
		}
		if err := createIfMissing(ctx, tb, acl); err != nil {
			return nil, err
		}
	}

	return db, nil
}

// creatable is satisfied by Syncbase hierarchy layers (app, db, table) that
// can be created and tested for existence.
type creatable interface {
	Create(ctx *context.T, acl access.Permissions) error
	Exists(ctx *context.T) (bool, error)
}

// createIfMissing checks if the given creatable layer exists and, if not,
// creates it.
// TODO(ivanpi): Syncbase client helpers for MustExist / CreateIfMissing.
func createIfMissing(ctx *context.T, target creatable, acl access.Permissions) error {
	if exists, err := target.Exists(ctx); err != nil {
		return err
	} else if exists {
		return nil
	}
	if err := target.Create(ctx, acl); err != nil && verror.ErrorID(err) != verror.ErrExist.ID {
		return err
	}
	return nil
}

// AddPermsForPrincipal adds to the ACL all specified permissions for all
// default blessings of the provided principal.
func AddPermsForPrincipal(acl *access.Permissions, principal security.Principal, tags ...access.Tag) {
	for _, pattern := range security.DefaultBlessingPatterns(principal) {
		AddPermsForPattern(acl, string(pattern), tags...)
	}
}

// AddPermsForPattern adds to the ACL all specified permissions for the
// specified pattern.
func AddPermsForPattern(acl *access.Permissions, pattern string, tags ...access.Tag) {
	for _, tag := range tags {
		acl.Add(security.BlessingPattern(pattern), string(tag))
	}
}
