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

// Measured methods for syncgroup management.

package measure

import (
	"fmt"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security/access"
	nosql_wire "v.io/v23/services/syncbase/nosql"
	"v.io/v23/syncbase/nosql"
	"v.io/v23/verror"
	"v.io/x/sensorlog/internal/config"
	"v.io/x/sensorlog/internal/sbmodel"
	"v.io/x/sensorlog/internal/sbmodel/keyutil"
	"v.io/x/sensorlog/internal/sbutil"
)

// InitSyncgroup creates the syncgroup for the measuring device devId, giving
// full configuration access to admin. The syncgroup uses sgPublishSb and
// sgMountTables for publishing (create/join) and syncing, respectively.
// InitSyncgroup must not be called concurrently for the same devId, or
// retried with different parameters for the same devId, otherwise behaviour
// is unspecified.
func InitSyncgroup(ctx *context.T, db nosql.Database, devId, admin, sgPublishSb string, sgMountTables []string) error {
	if err := keyutil.ValidateId(devId); err != nil {
		return fmt.Errorf("invalid devId: %v", err)
	}

	sgName := config.SyncgroupName(sgPublishSb, devId)
	// Check for syncgroup. If it already exists, we have nothing to do.
	if sgs, err := db.GetSyncgroupNames(ctx); err != nil {
		return err
	} else {
		for _, sg := range sgs {
			if sg == sgName {
				return nil
			}
		}
	}

	// Both measured and admin client have full permissions on the syncgroup.
	sgAcl := access.Permissions{}
	sbutil.AddPermsForPrincipal(&sgAcl, v23.GetPrincipal(ctx), access.AllTypicalTags()...)
	sbutil.AddPermsForPattern(&sgAcl, admin, access.AllTypicalTags()...)

	// Maps all syncgroup prefixes to ACLs.
	prefixSpec := make(map[nosql_wire.TableRow]access.Permissions)

	// StreamDef : <devId>
	// Admin client has full permissions, measured drops to readonly.
	prefixStreamDef := nosql_wire.TableRow{
		TableName: sbmodel.KStreamDef{}.Table(),
		Row:       devId,
	}
	aclStreamDef := access.Permissions{}
	sbutil.AddPermsForPrincipal(&aclStreamDef, v23.GetPrincipal(ctx), access.Resolve, access.Read)
	sbutil.AddPermsForPattern(&aclStreamDef, admin, access.AllTypicalTags()...)
	prefixSpec[prefixStreamDef] = aclStreamDef

	// DataPoint : <devId>
	// Admin client has full permissions, measured drops to read/write.
	prefixDataPoint := nosql_wire.TableRow{
		TableName: sbmodel.KDataPoint{}.Table(),
		Row:       devId,
	}
	aclDataPoint := access.Permissions{}
	sbutil.AddPermsForPrincipal(&aclDataPoint, v23.GetPrincipal(ctx), access.Resolve, access.Read, access.Write)
	sbutil.AddPermsForPattern(&aclDataPoint, admin, access.AllTypicalTags()...)
	prefixSpec[prefixDataPoint] = aclDataPoint

	var prefixes []nosql_wire.TableRow
	// Apply prefix ACLs to all syncgroup prefixes.
	for prefix, prefixAcl := range prefixSpec {
		// Ignore ErrNoAccess, assume we already dropped permissions.
		err := db.Table(prefix.TableName).SetPrefixPermissions(ctx, nosql.Prefix(prefix.Row), prefixAcl)
		if err != nil && verror.ErrorID(err) != verror.ErrNoAccess.ID {
			return err
		}
		prefixes = append(prefixes, prefix)
	}

	sgSpec := nosql_wire.SyncgroupSpec{
		Description: fmt.Sprintf("measured-main-%s", devId),
		Perms:       sgAcl,
		Prefixes:    prefixes,
		MountTables: sgMountTables,
	}
	sgMemberInfo := nosql_wire.SyncgroupMemberInfo{SyncPriority: config.SyncPriority}

	return db.Syncgroup(sgName).Create(ctx, sgSpec, sgMemberInfo)
}
