// 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"
	wire "v.io/v23/services/syncbase"
	"v.io/v23/syncbase"
	"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.
// TODO(ivanpi): Remove Resolve permissions when v.io/i/1110 is fixed.
func InitSyncgroup(ctx *context.T, db syncbase.Database, devId, admin, sgPublishSb string, sgMountTables []string) error {
	if err := keyutil.ValidateId(devId); err != nil {
		return fmt.Errorf("invalid devId: %v", err)
	}

	sgId := wire.Id{Name: config.SyncgroupName(devId), Blessing: "blessing"}
	// Check for syncgroup. If it already exists, we have nothing to do.
	if sgs, err := db.ListSyncgroups(ctx); err != nil {
		return err
	} else {
		for _, sg := range sgs {
			if sg == sgId {
				return nil
			}
		}
	}

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

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

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

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

	var prefixes []wire.CollectionRow
	// Apply prefix ACLs to all syncgroup prefixes.
	for prefix, _ := range prefixSpec {
		// TODO(ivanpi): Prefix ACLs have been removed, use collection ACLs.
		prefixes = append(prefixes, prefix)
	}

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

	return db.SyncgroupForId(sgId).Create(ctx, sgSpec, sgMemberInfo)
}
