// 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"
	wire "v.io/v23/services/syncbase"
	"v.io/v23/syncbase"
	"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, and initializing specified collections.
func CreateOrOpenDB(ctx *context.T, sbService string, collections []sbmodel.CollectionSpec) (syncbase.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)

	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)

	sbs := syncbase.NewService(sbService)
	// TODO(sadovsky): Refactor to reflect the change that eliminates the explicit
	// app layer. For now, we simply use AppName as database Id.Blessing.
	// TODO(ivanpi): Add schema version.
	db := sbs.DatabaseForId(wire.Id{Blessing: config.AppName, Name: config.DBName}, nil)
	if err := createIfMissing(ctx, db, aclFull); err != nil {
		return nil, err
	}

	// TODO(ivanpi): Add schemas when available.
	for _, cs := range collections {
		c := db.Collection(cs.Prototype.Collection())
		acl := aclReadOnly
		if !cs.ReadOnly {
			acl = aclFull
		}
		if err := createIfMissing(ctx, c, acl); err != nil {
			return nil, err
		}
	}

	return db, nil
}

// creatable is satisfied by Syncbase hierarchy layers (db, collection) 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))
	}
}
