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

// Package model defines functions for generating random sets of model
// databases, devices, and users that will be simulated in a syncbase longevity
// test.
package model

import (
	"fmt"
	"math/rand"
	"strings"
	"time"

	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/security/access"
	wire "v.io/v23/services/syncbase"
	"v.io/x/ref/services/syncbase/common"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func randomName(prefix string) string {
	return fmt.Sprintf("%s-%08x", prefix, rand.Int31())
}

// ===========
// Permissions
// ===========

// Permissions maps tags to Users who are included on that tag.
// TODO(nlacasse): Consider allowing blacklisted users with "NotIn" lists.
type Permissions map[string]UserSet

func (perms Permissions) ToWire(rootBlessing string) access.Permissions {
	p := access.Permissions{}
	for tag, users := range perms {
		for _, user := range users {
			userBlessing := user.Name
			if rootBlessing != "" {
				userBlessing = rootBlessing + security.ChainSeparator + user.Name
			}
			p.Add(security.BlessingPattern(userBlessing), tag)
		}
	}
	return p
}

// ===========
// Collections
// ===========

// Collection represents a syncbase collection.
// TODO(nlacasse): Put syncgroups in here?  It's a bit tricky because they need
// to have a host device name in their name, and the spec depends on the
// mounttable.
type Collection struct {
	// Name of the collection.
	Name string
	// Blessing of the collection.
	Blessing string
	// Permissions of the collection.
	Permissions Permissions
}

func (c *Collection) String() string {
	return fmt.Sprintf("{collection %v blessing=%v}", c.Name, c.Blessing)
}

func (c *Collection) Id() wire.Id {
	return wire.Id{
		Name:     c.Name,
		Blessing: c.Blessing,
	}
}

type CollectionSet []Collection

func (cols CollectionSet) String() string {
	strs := []string{}
	for _, col := range cols {
		strs = append(strs, col.String())
	}
	return fmt.Sprintf("[%s]", strings.Join(strs, ", "))
}

// ==========
// Syncgroups
// ==========

// Syncgroup represents a syncgroup.
type Syncgroup struct {
	HostDevice  *Device
	NameSuffix  string
	Description string
	Collections []Collection
	Permissions Permissions
	IsPrivate   bool
	// Devices which will attempt to create the syncgroup.
	CreatorDevices DeviceSet
	// Devices which will attempt to join the syncgroup.
	JoinerDevices DeviceSet
}

func (sg *Syncgroup) Name() string {
	return naming.Join(sg.HostDevice.Name, common.SyncbaseSuffix, sg.NameSuffix)
}

func (sg *Syncgroup) Spec(rootBlessing string) wire.SyncgroupSpec {
	collections := make([]wire.Id, len(sg.Collections))

	for i, col := range sg.Collections {
		collections[i] = col.Id()
	}

	return wire.SyncgroupSpec{
		Description: sg.Description,
		Collections: collections,
		Perms:       sg.Permissions.ToWire(rootBlessing),
		IsPrivate:   sg.IsPrivate,
	}
}

type SyncgroupSet []Syncgroup

func (sgs SyncgroupSet) String() string {
	strs := []string{}
	for _, sg := range sgs {
		strs = append(strs, sg.Name())
	}
	return fmt.Sprintf("[%s]", strings.Join(strs, ", "))
}

// =========
// Databases
// =========

// Database represents a syncbase database.  Each database corresponds to a
// single app.
type Database struct {
	// Name of the database.
	Name string
	// Blessing of the database.
	Blessing string
	// Collections.
	Collections CollectionSet
	// Syncgroups.
	Syncgroups SyncgroupSet
	// Permissions.
	Permissions Permissions
}

func (db *Database) String() string {
	return fmt.Sprintf("{database %v blessing=%v collections=%v syncgroups=%v perms=%v}", db.Name, db.Blessing, db.Collections, db.Syncgroups, db.Permissions.ToWire(""))
}

func (db *Database) Id() wire.Id {
	return wire.Id{
		Name:     db.Name,
		Blessing: db.Blessing,
	}
}

// DatabaseSet represents a set of Databases.
// TODO(nlacasse): Consider using a map here if uniqueness becomes an issue.
type DatabaseSet []*Database

// unique removes all duplicate entries from the DatabaseSet.
// TODO(nlacasse): Uniqueness is becoming an issue.  Make all Sets into maps.
func (dbs DatabaseSet) unique() DatabaseSet {
	found := map[*Database]struct{}{}
	udbs := DatabaseSet{}
	for _, db := range dbs {
		if _, ok := found[db]; !ok {
			udbs = append(udbs, db)
			found[db] = struct{}{}
		}
	}
	return udbs
}

// GenerateDatabaseSet generates a DatabaseSet with n databases.
// TODO(nlacasse): Generate collections and syncgroups.
// TODO(nlacasse): Generate clients.
func GenerateDatabaseSet(n int) DatabaseSet {
	dbs := DatabaseSet{}
	for i := 0; i < n; i++ {
		db := &Database{
			Name: randomName("db"),
		}
		dbs = append(dbs, db)
	}
	return dbs
}

// RandomSubset returns a random subset of the DatabaseSet with at least min
// and at most max databases.
func (dbs DatabaseSet) RandomSubset(min, max int) DatabaseSet {
	if min < 0 || min > len(dbs) || min > max {
		panic(fmt.Errorf("invalid arguments to RandomSubset: min=%v max=%v len(dbs)=%v", min, max, len(dbs)))
	}
	if max > len(dbs) {
		max = len(dbs)
	}
	n := min + rand.Intn(max-min+1)
	subset := make(DatabaseSet, n)
	for i, j := range rand.Perm(len(dbs))[:n] {
		subset[i] = dbs[j]
	}
	return subset
}

func (dbs DatabaseSet) String() string {
	r := make([]string, len(dbs))
	for i, j := range dbs {
		r[i] = j.Name
	}
	return fmt.Sprintf("[%s]", strings.Join(r, ", "))
}

// =======
// Devices
// =======

// ConnectivitySpec specifies the network connectivity of the device.
type ConnectivitySpec string

const (
	Online  ConnectivitySpec = "online"
	Offline ConnectivitySpec = "offline"
	// TODO(nlacasse): Add specs for latency, bandwidth, etc.
)

// DeviceSpec specifies the possible types of devices.
type DeviceSpec struct {
	// Maximum number of databases allowed on the device.
	MaxDatabases int
	// Types of connectivity allowed for the database.
	ConnectivitySpecs []ConnectivitySpec
}

// Some common DeviceSpecs.  It would be nice if these were consts, but go won't allow that.
var (
	LaptopSpec = DeviceSpec{
		MaxDatabases:      10,
		ConnectivitySpecs: []ConnectivitySpec{"online", "offline"},
	}

	PhoneSpec = DeviceSpec{
		MaxDatabases:      5,
		ConnectivitySpecs: []ConnectivitySpec{"online", "offline"},
	}

	CloudSpec = DeviceSpec{
		MaxDatabases:      100,
		ConnectivitySpecs: []ConnectivitySpec{"online"},
	}
	// TODO(nlacasse): Add more DeviceSpecs for tablet, desktop, camera,
	// wearable, etc.
)

// Device represents a device.
type Device struct {
	// Name of the device.
	Name string
	// Databases inluded on the device.
	Databases DatabaseSet
	// The device's spec.
	Spec DeviceSpec
	// Current connectivity spec for the device.  This value must be included
	// in Spec.ConnectivitySpecs.
	CurrentConnectivity ConnectivitySpec
	// Associated clients that will operate on this syncbase instance.  Clients
	// must be registered with control.RegisterClient.
	Clients []string
}

func (d Device) String() string {
	return fmt.Sprintf("{device %v databases=%v clients=%v}", d.Name, d.Databases, d.Clients)
}

// DeviceSet is a set of devices.
// TODO(nlacasse): Consider using a map here if uniqueness becomes an issue.
type DeviceSet []*Device

// GenerateDeviceSet generates a device set of size n.  The device spec for
// each device is chosen randomly from specs, and each device is given a
// non-empty set of databases taken from databases argument, obeying the maxium
// for the device spec.
func GenerateDeviceSet(n int, databases DatabaseSet, specs []DeviceSpec) DeviceSet {
	ds := DeviceSet{}
	for i := 0; i < n; i++ {
		// Pick a random spec.
		idx := rand.Intn(len(specs))
		spec := specs[idx]
		databases := databases.RandomSubset(1, spec.MaxDatabases)

		d := &Device{
			Name:      randomName("device"),
			Databases: databases,
			Spec:      spec,
			// Pick a random ConnectivitySpec from those allowed by the
			// DeviceSpec.
			CurrentConnectivity: spec.ConnectivitySpecs[rand.Intn(len(spec.ConnectivitySpecs))],
		}
		ds = append(ds, d)
	}
	return ds
}

func (ds DeviceSet) String() string {
	r := make([]string, len(ds))
	for i, j := range ds {
		r[i] = j.Name
	}
	return fmt.Sprintf("[%s]", strings.Join(r, ", "))
}

// Lookup returns the first Device in the DeviceSet with the given name, or nil
// if none exists.
func (ds DeviceSet) Lookup(name string) *Device {
	for _, d := range ds {
		if d.Name == name {
			return d
		}
	}
	return nil
}

// Topology is an adjacency matrix specifying the connection type between
// devices.
// TODO(nlacasse): For now we only specify which devices are reachable by each
// device.
type Topology map[*Device]DeviceSet

func (top Topology) String() string {
	str := ""
	for d, ds := range top {
		str += fmt.Sprintf("%v can send to %v\n", d.Name, ds)
	}
	return str
}

// GenerateTopology generates a Topology on the given DeviceSet.  The affinity
// argument specifies the probability that any two devices are connected.  We
// ensure that the generated topology is symmetric, but we do *not* guarantee
// that it is connected.
// TODO(nlacasse): Have more fine-grained affinity taking into account the
// DeviceSpec of each device.  E.g. Desktop is likely to be connected to the
// cloud, but less likely to be connected to a watch.
func GenerateTopology(devices DeviceSet, affinity float64) Topology {
	top := Topology{}
	for i, d1 := range devices {
		// All devices are connected to themselves.
		top[d1] = append(top[d1], d1)
		for _, d2 := range devices[i+1:] {
			connected := rand.Float64() <= affinity
			if connected {
				top[d1] = append(top[d1], d2)
				top[d2] = append(top[d2], d1)
			}
		}
	}
	return top
}

// =====
// Users
// =====

// User represents a user.
type User struct {
	// The user's name.
	Name string
	// The user's devices.  All databases in the user's devices will be
	// included in the user's Databases.
	Devices DeviceSet
}

// Databases returns all databases contained on the user's devices.
func (user *User) Databases() DatabaseSet {
	dbs := DatabaseSet{}
	for _, dev := range user.Devices {
		dbs = append(dbs, dev.Databases...)
	}
	return dbs.unique()
}

func (user *User) String() string {
	return fmt.Sprintf(`{user %v devices=%v}`, user.Name, user.Devices)
}

// UserSet is a set of users.
type UserSet []*User

// UserOpts specifies the options to use when creating a random user.
type UserOpts struct {
	MaxDatabases int
	MaxDevices   int
	MinDevices   int
}

// GenerateUser generates a random user with nonempty set of databases from the
// given database set and n devices.
// TODO(nlacasse): Should DatabaseSet be in UserOpts?
func GenerateUser(dbs DatabaseSet, opts UserOpts) *User {
	// TODO(nlacasse): Make this a parameter?
	specs := []DeviceSpec{
		LaptopSpec,
		PhoneSpec,
		CloudSpec,
	}

	databases := dbs.RandomSubset(1, opts.MaxDatabases)
	numDevices := opts.MinDevices
	if opts.MaxDevices > opts.MinDevices {
		numDevices += rand.Intn(opts.MaxDevices - opts.MinDevices)
	}
	devices := GenerateDeviceSet(numDevices, databases, specs)

	return &User{
		Name:    randomName("user"),
		Devices: devices,
	}
}

// ========
// Universe
// ========

type Universe struct {
	// All users in the universe.
	Users UserSet
	// Description of device connectivity.
	Topology Topology
}

// Databases returns all databases contained in the universe.
func (u *Universe) Databases() DatabaseSet {
	dbs := DatabaseSet{}
	for _, user := range u.Users {
		dbs = append(dbs, user.Databases()...)
	}
	return dbs.unique()
}

func (u *Universe) String() string {
	// Collect all device and user descriptions with a newline in between each.
	devStrings := []string{}
	userStrings := []string{}
	for _, user := range u.Users {
		userStrings = append(userStrings, user.String())
		for _, dev := range user.Devices {
			devStrings = append(devStrings, dev.String())
		}
	}
	devString := strings.Join(devStrings, "\n")
	userString := strings.Join(userStrings, "\n")

	dbStrings := []string{}
	for _, db := range u.Databases() {
		dbStrings = append(dbStrings, db.String())
	}
	dbString := strings.Join(dbStrings, "\n")

	return fmt.Sprintf(`Databases:
%v

Devices:
%v

Users:
%v

Topology:
%v`, dbString, devString, userString, u.Topology)
}

// UniverseOpts specifies the options to use when creating a random universe.
type UniverseOpts struct {
	// Probability that any two devices are connected
	DeviceAffinity float64
	// Maximum number of databases in the universe.
	MaxDatabases int
	// Number of users in the universe.
	NumUsers int
	// Maximum number of databases for any user.
	MaxDatabasesPerUser int
	// Maximum number of devices for any user.
	MaxDevicesPerUser int
	// Minimum number of devices for any user.
	MinDevicesPerUser int
}

func GenerateUniverse(opts UniverseOpts) Universe {
	dbs := GenerateDatabaseSet(opts.MaxDatabases)
	userOpts := UserOpts{
		MaxDatabases: opts.MaxDatabasesPerUser,
		MaxDevices:   opts.MaxDevicesPerUser,
		MinDevices:   opts.MinDevicesPerUser,
	}
	users := UserSet{}
	devices := DeviceSet{}
	for i := 0; i < opts.NumUsers; i++ {
		user := GenerateUser(dbs, userOpts)
		users = append(users, user)
		devices = append(devices, user.Devices...)
	}

	return Universe{
		Users:    users,
		Topology: GenerateTopology(devices, opts.DeviceAffinity),
	}
}
