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

import (
	"runtime"
	"strings"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/verror"
	"v.io/x/ref/lib/apilog"
)

var (
	errNoServers = verror.Register(pkgPath+".errNoServers", verror.NoRetry, "{1} {2} No servers found to resolve query {_}")
)

// resolveAgainstMountTable asks each server in e.Servers that might be a mounttable to resolve e.Name.  The requests
// are parallelized by the client rpc code.
func (ns *namespace) resolveAgainstMountTable(ctx *context.T, client rpc.Client, e *naming.MountEntry, opts ...rpc.CallOpt) (*naming.MountEntry, error) {
	// Run through the server list looking for answers in the cache or servers that aren't mounttables.
	change := false
	for _, s := range e.Servers {
		// If the server was not specified as an endpoint (perhaps as host:port)
		// then we really don't know if this is a mounttable or not.  Check the
		// cache to see if we've tried in the recent past and it came back as not
		// a mounttable.
		if ns.resolutionCache.isNotMT(s.Server) {
			change = true
			continue
		}

		// Check the cache.  If its there, we're done.
		n := naming.JoinAddressName(s.Server, e.Name)
		if ne, err := ns.resolutionCache.lookup(ctx, n); err == nil {
			ctx.VI(2).Infof("resolveAMT %s from cache -> %v", n, convertServersToStrings(ne.Servers, ne.Name))
			return &ne, nil
		}
	}
	// We had at least one server that wasn't a mount table.  Create a new mount entry without those servers.
	if change {
		ne := *e
		ne.Servers = nil
		for _, s := range e.Servers {
			if !ns.resolutionCache.isNotMT(s.Server) {
				ne.Servers = append(ne.Servers, s)
			}
		}
		e = &ne
	}
	// If we have no servers to query, give up.
	if len(e.Servers) == 0 {
		ctx.VI(2).Infof("resolveAMT %s -> No servers", e.Name)
		return nil, verror.New(errNoServers, ctx)
	}
	// We have preresolved the servers.  Pass the mount entry to the call.
	opts = append(opts, options.Preresolved{e})
	callCtx := ctx
	if _, hasDeadline := ctx.Deadline(); !hasDeadline {
		// Only set a per-call timeout if a deadline has not already
		// been set.
		var cancel func()
		callCtx, cancel = withTimeout(ctx)
		defer cancel()
	}
	entry := new(naming.MountEntry)
	if err := client.Call(callCtx, e.Name, "ResolveStep", nil, []interface{}{entry}, opts...); err != nil {
		// If it wasn't a mounttable remember that fact.  The check for the __ is for
		// the debugging hack in the local namespace of every server.  That part never
		// answers mounttable RPCs and shouldn't make us think this isn't a mounttable
		// server.
		if notAnMT(err) && !strings.HasPrefix(e.Name, "__") {
			for _, s := range e.Servers {
				ns.resolutionCache.setNotMT(s.Server)
			}
		}
		return nil, err
	}
	// Add result to cache for each server that may have returned it.
	for _, s := range e.Servers {
		n := naming.JoinAddressName(s.Server, e.Name)
		ns.resolutionCache.remember(ctx, n, entry)
	}
	ctx.VI(2).Infof("resolveAMT %s -> %v", e.Name, entry)
	return entry, nil
}

func terminal(e *naming.MountEntry) bool {
	return len(e.Name) == 0
}

func hasEndpointPrefix(name string) bool {
	if name == "" || naming.Rooted(name) {
		return false
	}
	elems := strings.SplitN(name, "/", 2)
	_, err := naming.ParseEndpoint(elems[0])
	return err == nil
}

// Resolve implements v.io/v23/naming.Namespace.
func (ns *namespace) Resolve(ctx *context.T, name string, opts ...naming.NamespaceOpt) (*naming.MountEntry, error) {
	defer apilog.LogCallf(ctx, "name=%.10s...,opts...=%v", name, opts)(ctx, "") // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT

	e, err := ns.resolveInternal(ctx, name, opts...)
	// If the resolution failed and it appears that the name starts with an
	// endpoint but was mistakenly passed in un-rooted, add a sub error to
	// point that out to the client.

	// TODO(caprita): Consider doing this also for ResolveShallow and
	// ResolveToMountTable.
	if err != nil && hasEndpointPrefix(name) {
		verrorE := verror.Convert(verror.IDAction{}, ctx, err)
		err = verror.AddSubErrs(verrorE, nil, verror.SubErr{"Did you mean", verror.E{Msg: "/" + name}, verror.Print})
	}
	return e, err
}

func (ns *namespace) resolveInternal(ctx *context.T, name string, opts ...naming.NamespaceOpt) (*naming.MountEntry, error) {
	// If caller supplied a mount entry, use it.
	e, skipResolution := preresolved(opts)
	if e != nil {
		return e, nil
	}
	// Expand any relative name.
	e, _ = ns.rootMountEntry(name, opts...)
	if ctx.V(2) {
		_, file, line, _ := runtime.Caller(1)
		ctx.Infof("Resolve(%s) called from %s:%d", name, file, line)
		ctx.Infof("Resolve(%s) -> rootEntry %v", name, *e)
	}
	// If caller didn't want resolution, use expanded name.
	if skipResolution {
		return e, nil
	}
	if len(e.Servers) == 0 {
		return nil, verror.New(naming.ErrNoSuchName, ctx, name)
	}
	client := v23.GetClient(ctx)
	callOpts := getCallOpts(opts)

	// Iterate walking through mount table servers.
	for remaining := ns.maxResolveDepth; remaining > 0; remaining-- {
		if ctx.V(2) {
			ctx.Infof("Resolve(%s) loop %v", name, *e)
		}
		if !e.ServesMountTable {
			if ctx.V(1) {
				ctx.Infof("Resolve(%s) -> %v", name, *e)
			}
			return e, nil
		}
		var err error
		curr := e
		if e, err = ns.resolveAgainstMountTable(ctx, client, curr, callOpts...); err != nil {
			// Lots of reasons why another error can happen.  We are trying
			// to single out "this isn't a mount table".
			if notAnMT(err) {
				ctx.VI(1).Infof("Resolve(%s) -> %v", name, curr)
				return curr, nil
			}
			if verror.ErrorID(err) == naming.ErrNoSuchNameRoot.ID {
				err = verror.New(naming.ErrNoSuchName, ctx, name)
			}
			ctx.VI(1).Infof("Resolve(%s) -> (%s: %v)", err, name, curr)
			return nil, err
		}
	}
	return nil, verror.New(naming.ErrResolutionDepthExceeded, ctx)
}

// ShallowResolve implements v.io/v23/naming.Namespace.
func (ns *namespace) ShallowResolve(ctx *context.T, name string, opts ...naming.NamespaceOpt) (*naming.MountEntry, error) {
	defer apilog.LogCallf(ctx, "name=%.10s...,opts...=%v", name, opts)(ctx, "") // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT

	// Find the containing mount table.
	me, err := ns.ResolveToMountTable(ctx, name, opts...)
	if err != nil {
		return nil, err
	}
	if terminal(me) {
		return me, nil
	}

	// Resolve the entry directly.
	client := v23.GetClient(ctx)
	entry := new(naming.MountEntry)
	err = client.Call(ctx, name, "ResolveStep", nil, []interface{}{entry}, append(getCallOpts(opts), options.Preresolved{me})...)
	return entry, err
}

// ResolveToMountTable implements v.io/v23/naming.Namespace.
func (ns *namespace) ResolveToMountTable(ctx *context.T, name string, opts ...naming.NamespaceOpt) (*naming.MountEntry, error) {
	defer apilog.LogCallf(ctx, "name=%.10s...,opts...=%v", name, opts)(ctx, "") // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
	e, _ := ns.rootMountEntry(name, opts...)
	if ctx.V(2) {
		_, file, line, _ := runtime.Caller(1)
		ctx.Infof("ResolveToMountTable(%s) called from %s:%d", name, file, line)
		ctx.Infof("ResolveToMountTable(%s) -> rootNames %v", name, e)
	}
	if len(e.Servers) == 0 {
		return nil, verror.New(naming.ErrNoMountTable, ctx)
	}
	callOpts := getCallOpts(opts)
	client := v23.GetClient(ctx)
	last := e
	for remaining := ns.maxResolveDepth; remaining > 0; remaining-- {
		ctx.VI(2).Infof("ResolveToMountTable(%s) loop %v", name, e)
		var err error
		curr := e
		// If the next name to resolve doesn't point to a mount table, we're done.
		if !e.ServesMountTable || terminal(e) {
			ctx.VI(1).Infof("ResolveToMountTable(%s) -> %v", name, last)
			return last, nil
		}
		if e, err = ns.resolveAgainstMountTable(ctx, client, e, callOpts...); err != nil {
			if verror.ErrorID(err) == naming.ErrNoSuchNameRoot.ID {
				ctx.VI(1).Infof("ResolveToMountTable(%s) -> %v (NoSuchRoot: %v)", name, last, curr)
				return last, nil
			}
			if verror.ErrorID(err) == naming.ErrNoSuchName.ID {
				ctx.VI(1).Infof("ResolveToMountTable(%s) -> %v (NoSuchName: %v)", name, curr, curr)
				return curr, nil
			}
			// Lots of reasons why another error can happen.  We are trying
			// to single out "this isn't a mount table".
			if notAnMT(err) {
				ctx.VI(1).Infof("ResolveToMountTable(%s) -> %v", name, last)
				return last, nil
			}
			// TODO(caprita): If the server is unreachable for
			// example, we may still want to return its parent
			// mounttable rather than an error.
			ctx.VI(1).Infof("ResolveToMountTable(%s) -> %v", name, err)
			return nil, err
		}
		last = curr
	}
	return nil, verror.New(naming.ErrResolutionDepthExceeded, ctx)
}

// FlushCache flushes the most specific entry found for name.  It returns true if anything was
// actually flushed.
func (ns *namespace) FlushCacheEntry(ctx *context.T, name string) bool {
	defer apilog.LogCallf(nil, "name=%.10s...", name)(nil, "") // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
	flushed := false
	for _, n := range ns.rootName(name) {
		// Walk the cache as we would in a resolution.  Unlike a resolution, we have to follow
		// all branches since we want to flush all entries at which we might end up whereas in a resolution,
		// we stop with the first branch that works.
		if e, err := ns.resolutionCache.lookup(ctx, n); err == nil {
			// Recurse.
			for _, s := range e.Servers {
				flushed = flushed || ns.FlushCacheEntry(ctx, naming.Join(s.Server, e.Name))
			}
			if !flushed {
				// Forget the entry we just used.
				ns.resolutionCache.forget(ctx, []string{naming.TrimSuffix(n, e.Name)})
				flushed = true
			}
		}
	}
	return flushed
}

func preresolved(opts []naming.NamespaceOpt) (*naming.MountEntry, bool) {
	for _, o := range opts {
		if v, ok := o.(options.Preresolved); ok {
			return v.Resolution, true
		}
	}
	return nil, false
}
