// Copyright 2016 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 internal

import (
	"math"
	"math/rand"
	"path"
	"reflect"
	"strings"
	"time"

	"v.io/v23/context"
	"v.io/v23/conventions"
	"v.io/v23/glob"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/security/access"
	v23mt "v.io/v23/services/mounttable"
	"v.io/v23/verror"
)

const pkgPath = "v.io/x/ref/services/mounttable/btmtd/internal"

var (
	errMalformedAddress = verror.Register(pkgPath+".errMalformedAddress", verror.NoRetry, "{1:}{2:} malformed address {3} for mounted server {4}{:_}")
	errNotEmpty         = verror.Register(pkgPath+".errNotEmpty", verror.NoRetry, "{1:}{2:} cannot delete {3}: has children{:_}")
	errConcurrentAccess = verror.Register(pkgPath+".errConcurrentAccess", verror.RetryRefetch, "{1:}{2:} concurrent access caused conflict{:_}")
)

func shouldAbort(ctx *context.T) error {
	select {
	case <-ctx.Done():
		return verror.NewErrAborted(ctx)
	default:
		return nil
	}
}

func op(ctx *context.T, f func() error) (err error) {
	for {
		if err = shouldAbort(ctx); err != nil {
			return
		}
		if err = f(); verror.ErrorID(err) == errConcurrentAccess.ID {
			ctx.VI(2).Infof("Concurrent access conflict detected: %v", err)
			time.Sleep(time.Duration(rand.Intn(50)) * time.Millisecond)
			continue
		}
		return
	}
}

type mounttable struct {
	suffix    string
	globalAcl *access.AccessList
	bt        *BigTable
}

// Mount a server onto the name in the receiver.
func (mt *mounttable) Mount(ctx *context.T, call rpc.ServerCall, server string, ttl uint32, flags naming.MountFlag) error {
	ctx.VI(2).Infof("%q.Mount(%q, %d, %v)", mt.suffix, server, ttl, flags)
	if ttl == 0 {
		ttl = math.MaxUint32
	}
	// Make sure the server address is reasonable.
	ep := server
	if naming.Rooted(server) {
		ep, _ = naming.SplitAddressName(server)
	}
	if _, err := naming.ParseEndpoint(ep); err != nil {
		return verror.New(errMalformedAddress, ctx, ep, server)
	}

	return op(ctx, func() error {
		n, err := mt.accessNodeCreate(ctx, mt.suffix, call.Security())
		if err != nil {
			return err
		}
		if err := mt.authorize(ctx, call.Security(), n.permissions, v23mt.Mount, v23mt.Admin); err != nil {
			return err
		}
		return n.mount(ctx, server, clock.Now().Add(time.Duration(ttl)*time.Second), flags)
	})
}

// Unmount removes servers from the name in the receiver. If server is specified, only that
// server is removed.
func (mt *mounttable) Unmount(ctx *context.T, call rpc.ServerCall, server string) error {
	ctx.VI(2).Infof("%q.Unmount(%q)", mt.suffix, server)

	return op(ctx, func() error {
		n, err := mt.accessNodeRead(ctx, mt.suffix, call.Security())
		if err != nil {
			return err
		}
		if err := mt.authorize(ctx, call.Security(), n.permissions, v23mt.Mount, v23mt.Admin); err != nil {
			return err
		}
		return n.unmount(ctx, server)
	})
}

// Delete removes the receiver.  If the receiver has children, it will not
// be removed unless deleteSubtree is true in which case the whole subtree is
// removed.
func (mt *mounttable) Delete(ctx *context.T, call rpc.ServerCall, deleteSubtree bool) error {
	ctx.VI(2).Infof("%q.Delete(%v)", mt.suffix, deleteSubtree)

	if mt.suffix == "" {
		return verror.New(verror.ErrNoAccess, ctx, "")
	}

	return op(ctx, func() error {
		n, err := mt.accessNodeRead(ctx, mt.suffix, call.Security())
		if verror.ErrorID(err) == naming.ErrNoSuchName.ID {
			return nil
		}
		if err != nil {
			return err
		}
		// Caller must have Admin access on either the node itself or
		// its parent.
		if err := mt.authorize(ctx, call.Security(), n.permissions, v23mt.Admin); err != nil {
			parent, _ := path.Split(mt.suffix)
			if p, _ := mt.accessNodeRead(ctx, parent, call.Security()); p == nil {
				return err
			} else if err2 := mt.authorize(ctx, call.Security(), p.permissions, v23mt.Admin); err2 != nil {
				return err
			}
		}
		return n.deleteAndGC(ctx, deleteSubtree)
	})
}

// ResolveStep takes the next step in resolving a name.  Returns the next
// servers to query and the suffix at those servers.
func (mt *mounttable) ResolveStep(ctx *context.T, call rpc.ServerCall) (entry naming.MountEntry, err error) {
	ctx.VI(2).Infof("%q.ResolveStep()", mt.suffix)

	n, remainder, err := mt.accessNodeWithServers(ctx, mt.suffix, call.Security())
	if err != nil {
		return entry, err
	}
	if n == nil {
		entry.Name = mt.suffix
		err = verror.New(naming.ErrNoSuchName, ctx, mt.suffix)
		return
	}
	entry.Name = remainder
	entry.Servers = make([]naming.MountedServer, len(n.servers))
	for i, s := range n.servers {
		entry.Servers[i] = s
		entry.ServesMountTable = n.mountFlags.MT
		entry.IsLeaf = n.mountFlags.Leaf
	}
	return entry, nil
}

// Glob__ finds matches in the namespace.  If we reach a mount point before
// matching the whole pattern, return that mount point.
func (mt *mounttable) Glob__(ctx *context.T, call rpc.GlobServerCall, g *glob.Glob) error {
	ctx.VI(2).Infof("%q.Glob__(%q)", mt.suffix, g)

	n, remainder, err := mt.accessNodeWithServers(ctx, mt.suffix, call.Security())
	if err != nil {
		return err
	}
	if n != nil {
		me := naming.MountEntry{
			Name:             "",
			Servers:          make([]naming.MountedServer, len(n.servers)),
			ServesMountTable: n.mountFlags.MT,
			IsLeaf:           n.mountFlags.Leaf,
		}
		for i, s := range n.servers {
			me.Servers[i].Server = naming.Join(s.Server, remainder)
			me.Servers[i].Deadline = s.Deadline
		}
		call.SendStream().Send(naming.GlobReplyEntry{Value: me})
		return nil
	}

	type gState struct {
		name string
		g    *glob.Glob
	}
	queue := []gState{gState{"", g}}
	for len(queue) != 0 {
		if err := shouldAbort(ctx); err != nil {
			return err
		}
		state := queue[0]
		queue = queue[1:]

		n, err := mt.accessNodeRead(ctx, naming.Join(mt.suffix, state.name), call.Security())
		if err != nil {
			ctx.VI(2).Infof("caller doesn't have access to %s", state.name)
			continue
		}
		if n == nil {
			continue
		}
		if len(n.servers) > 0 {
			me := naming.MountEntry{
				Name:             state.name,
				Servers:          make([]naming.MountedServer, len(n.servers)),
				ServesMountTable: n.mountFlags.MT,
				IsLeaf:           n.mountFlags.Leaf,
			}
			for i, s := range n.servers {
				me.Servers[i] = s
			}
			call.SendStream().Send(naming.GlobReplyEntry{Value: me})
			continue
		}
		if state.g.Len() == 0 {
			call.SendStream().Send(naming.GlobReplyEntry{Value: naming.MountEntry{Name: state.name}})
		}
		if state.g.Empty() {
			continue
		}
		matcher, left := state.g.Head(), state.g.Tail()
		for _, child := range n.children {
			if matcher.Match(child) {
				// TODO(rthellend): We should protect against large query results
				// that could blow up memory usage.
				queue = append(queue, gState{naming.Join(state.name, child), left})
			}
		}
	}
	return nil
}

// SetPermissions replaces the current Permissions for an object.  version
// allows for optional, optimistic concurrency control.  If non-empty,
// version's value must come from GetPermissions.  If any client has
// successfully called SetPermissions in the meantime, the version will be
// stale and SetPermissions will fail.  If empty, SetPermissions performs an
// unconditional update.
func (mt *mounttable) SetPermissions(ctx *context.T, call rpc.ServerCall, perms access.Permissions, version string) error {
	ctx.VI(2).Infof("%q.SetPermissions(%#v, %q)", mt.suffix, perms, version)

	// If the user is trying to set permissions on a node such that the
	// user will no longer have admin access, add the user as Admin.
	if err := mt.authorize(ctx, call.Security(), perms, v23mt.Admin); err != nil {
		blessings, _ := security.RemoteBlessingNames(ctx, call.Security())
		for _, b := range blessings {
			perms.Add(security.BlessingPattern(b), string(v23mt.Admin))
		}
	}
	perms.Normalize()

	return op(ctx, func() error {
		n, err := mt.accessNodeCreate(ctx, mt.suffix, call.Security())
		if err != nil {
			return err
		}
		if err := mt.authorize(ctx, call.Security(), n.permissions, v23mt.Admin); err != nil {
			return err
		}
		if version != "" && n.version != version {
			return verror.NewErrBadVersion(ctx)
		}
		return n.setPermissions(ctx, perms)
	})
}

// GetPermissions returns the complete, current Permissions for an object. The
// returned version can be passed to a subsequent call to SetPermissions for
// optimistic concurrency control. A successful call to SetPermissions will
// invalidate version, and the client must call GetPermissions again to get
// the current version.
func (mt *mounttable) GetPermissions(ctx *context.T, call rpc.ServerCall) (perms access.Permissions, version string, err error) {
	ctx.VI(2).Infof("%q.GetPermissions()", mt.suffix)

	var n *mtNode
	if n, err = mt.accessNodeRead(ctx, mt.suffix, call.Security()); err != nil {
		return
	}
	return n.permissions, n.version, nil
}

func (mt *mounttable) authorize(ctx *context.T, call security.Call, perms access.Permissions, tags ...v23mt.Tag) error {
	if l, r := call.LocalBlessings().PublicKey(), call.RemoteBlessings().PublicKey(); l != nil && r != nil && reflect.DeepEqual(l, r) {
		return nil
	}
	blessings, invalid := security.RemoteBlessingNames(ctx, call)
	for _, tag := range tags {
		if acl, exists := perms[string(tag)]; exists && acl.Includes(blessings...) {
			return nil
		}
	}
	if mt.globalAcl != nil {
		if mt.globalAcl.Includes(blessings...) {
			return nil
		}
	}
	return access.NewErrNoPermissions(ctx, blessings, invalid, string(tags[0]))
}

// accessNode returns the requested mounttable node after verifying that the
// caller is authorized to access it. Missing nodes are created if 'create' is
// true and the caller has 'Create' permission on the parent.
//
// If withServers is true, returns the first node within 'name' that has
// mounted servers, and the remaining part is returned as a string.
//
// Example:
//   a -> b -> c
// If b has a mounted server,
//  accessNode(.., "a/b", false, true, ..) returns (b, "")
//  accessNode(.., "a/b/c", false, true, ..) returns (b, "c")
//  accessNode(.., "a/b", false, false, ..) returns (b, "")
//  accessNode(.., "a/b/c", false, false, ..) returns (c, "")
func (mt *mounttable) accessNode(ctx *context.T, name string, create, withServers bool, call security.Call) (*mtNode, string, error) {
start:
	var (
		n, parent *mtNode
		current   string
		elems     = append([]string{""}, strings.Split(name, "/")...)
	)

	for len(elems) > 0 {
		if err := shouldAbort(ctx); err != nil {
			return nil, "", err
		}

		elem := elems[0]
		elems = elems[1:]
		current = naming.Join(current, elem)

		var err error
		n, err = getNode(ctx, mt.bt, current)

		switch {
		case err != nil:
			return nil, "", err
		case n == nil:
			if parent == nil {
				return nil, "", verror.New(naming.ErrNoSuchNameRoot, ctx, current)
			}
			if !create {
				return nil, "", verror.New(naming.ErrNoSuchName, ctx, current)
			}
			if err := mt.authorize(ctx, call, parent.permissions, v23mt.Create, v23mt.Admin); err != nil {
				return nil, "", err
			}
			var perms access.Permissions
			if perms = templatePermissions(parent.permissions, elem); perms == nil {
				perms = parent.permissions.Copy()
				if current == name {
					names, _ := security.RemoteBlessingNames(ctx, call)
					for _, n := range names {
						perms.Add(security.BlessingPattern(n), string(v23mt.Admin))
					}
				}
			}
			perms.Normalize()
			n, err = parent.createChild(ctx, elem, perms, pickCreator(ctx, call))
			if err != nil {
				return nil, "", err
			}
		default:
			deleted, err := n.gc(ctx)
			if deleted || verror.ErrorID(err) == errConcurrentAccess.ID {
				goto start
			}
			if err != nil {
				return nil, "", err
			}
		}
		if err := mt.authorize(ctx, call, n.permissions, v23mt.Resolve, v23mt.Read, v23mt.Admin); err != nil {
			return nil, "", err
		}
		if withServers && len(n.servers) > 0 {
			return n, naming.Join(elems...), nil
		}
		parent = n
	}
	if withServers {
		return nil, "", nil
	}
	return n, "", nil
}

func (mt *mounttable) accessNodeRead(ctx *context.T, name string, call security.Call) (*mtNode, error) {
	n, _, err := mt.accessNode(ctx, name, false, false, call)
	return n, err
}

func (mt *mounttable) accessNodeCreate(ctx *context.T, name string, call security.Call) (*mtNode, error) {
	n, _, err := mt.accessNode(ctx, name, true, false, call)
	return n, err
}

func (mt *mounttable) accessNodeWithServers(ctx *context.T, name string, call security.Call) (*mtNode, string, error) {
	return mt.accessNode(ctx, name, false, true, call)
}

func templatePermissions(perms access.Permissions, child string) access.Permissions {
	var templatePerms access.Permissions
	for tag, acl := range perms {
		if !strings.HasPrefix(tag, "%%/") {
			continue
		}
		tmpAcl := access.AccessList{
			In:    make([]security.BlessingPattern, len(acl.In)),
			NotIn: make([]string, len(acl.NotIn)),
		}
		for i, b := range acl.In {
			tmpAcl.In[i] = security.BlessingPattern(strings.Replace(string(b), "%%", child, -1))
		}
		for i, b := range acl.NotIn {
			tmpAcl.NotIn[i] = strings.Replace(b, "%%", child, -1)
		}
		if templatePerms == nil {
			templatePerms = make(access.Permissions)
		}
		templatePerms[strings.TrimPrefix(tag, "%%/")] = tmpAcl
	}
	return templatePerms
}

func pickCreator(ctx *context.T, call security.Call) string {
	return conventions.GetClientUserIds(ctx, call)[0]
}
