// 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/internal/config"
	"v.io/x/sensorlog/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))
	}
}
