// 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.
// TODO(ivanpi): Remove Resolve permissions when v.io/i/1110 is fixed.
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.Read, access.Admin)
	sbutil.AddPermsForPattern(&sgAcl, admin, access.Read, access.Admin)

	// 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.Resolve, access.Read, access.Write, access.Admin)
	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.Resolve, access.Read, access.Write, access.Admin)
	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)
}
