// 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_lite/internal/config"
	"v.io/x/sensorlog_lite/internal/sbmodel"
	"v.io/x/sensorlog_lite/internal/sbmodel/keyutil"
	"v.io/x/sensorlog_lite/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)
}
