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

import (
	"reflect"
	"strconv"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/flow"
	"v.io/v23/naming"
	"v.io/v23/rpc/version"
	"v.io/v23/security"
	connpackage "v.io/x/ref/runtime/internal/flow/conn"
	"v.io/x/ref/runtime/internal/flow/flowtest"
	_ "v.io/x/ref/runtime/protocols/local"
	"v.io/x/ref/test"
	"v.io/x/ref/test/goroutines"
)

func init() {
	flow.RegisterProtocol("resolve", &resolveProtocol{
		protocol:  "local",
		addresses: []string{"address"},
	})
	p, _ := flow.RegisteredProtocol("local")
	flow.RegisterProtocol("wrong", p)
}

var nextrid uint64 = 100

func makeEPs(ctx *context.T, addr string) (ep, nullep, wprotoep, waddrep, waddrprotoep, resolvep naming.Endpoint) {
	ep = naming.Endpoint{
		Protocol:  "local",
		Address:   addr,
		RoutingID: naming.FixedRoutingID(nextrid),
	}.WithBlessingNames(unionBlessing(ctx, "A", "B", "C"))
	nextrid++

	nullep = ep
	nullep.RoutingID = naming.NullRoutingID
	wprotoep = nullep
	wprotoep.Protocol = "wrong"
	waddrep = nullep
	waddrep.Address = "wrong"
	resolvep = nullep
	resolvep.Protocol = "resolve"
	resolvep.Address = "wrong"
	waddrprotoep = ep
	waddrprotoep.Protocol = "wrong"
	waddrprotoep.Address = "wrong"
	return
}

func modep(ep naming.Endpoint, field string, value interface{}) naming.Endpoint {
	reflect.ValueOf(ep).FieldByName(field).Set(reflect.ValueOf(value))
	return ep
}

func makeEP(ctx *context.T, protocol, address string, rid uint64, blessings ...string) naming.Endpoint {
	routingID := naming.NullRoutingID
	if rid != 0 {
		routingID = naming.FixedRoutingID(rid)
	}
	return naming.Endpoint{
		Protocol:  protocol,
		Address:   address,
		RoutingID: routingID,
	}.WithBlessingNames(blessings)
}

func TestCacheReserve(t *testing.T) {
	defer goroutines.NoLeaks(t, leakWaitTime)()
	ctx, shutdown := test.V23Init()
	defer shutdown()

	c := NewConnCache(0)
	nullep := makeEP(ctx, "local", "a1", 0, "b1")
	oneep := makeEP(ctx, "local", "a1", 1, "b1")
	twoep := makeEP(ctx, "local", "a1", 2, "b1")
	proxyep := makeEP(ctx, "local", "a1", 3, "b1")

	r1 := c.Reserve(ctx, oneep)
	if r1 == nil {
		t.Error("expected non-nil reservation.")
	}

	// That will have reserved both the address and the path.
	// A second reservation should return nil.
	if nr := c.Reserve(ctx, oneep); nr != nil {
		t.Errorf("got %v, want nil", nr)
	}
	if nr := c.Reserve(ctx, nullep); nr != nil {
		t.Errorf("got %v, want nil", nr)
	}

	// Reserving the proxy now will return a reservation for only
	// the proxies RID, since at this point we don't know the proxies
	// RID.
	pr := c.Reserve(ctx, proxyep)
	if pr == nil {
		t.Errorf("epected non-nil reservation")
	}

	// Reserving a different RID, but the same address will result in a path
	// reservation.
	r2 := c.Reserve(ctx, twoep)
	if r2 == nil {
		t.Errorf("expected non-nil reservation.")
	}

	// Since r1 has reserved the proxy address, it's ProxyConn should return nil.
	if pc := r1.ProxyConn(); pc != nil {
		t.Errorf("got %v, expected nil.", pc)
	}
	proxycaf := makeConnAndFlow(t, ctx, proxyep)
	defer proxycaf.stop(ctx)
	onecaf := makeConnAndFlow(t, ctx, oneep)
	defer onecaf.stop(ctx)
	r1.Unreserve(onecaf.c, proxycaf.c, nil)

	// Now, asking for the ProxyConn on the proxy reservation should find
	// the proxy, since we just inserted it.
	if pc := pr.ProxyConn().(*connpackage.Conn); pc != proxycaf.c {
		t.Errorf("got %v, expected %v", pc, proxycaf.c)
	}

	// Now that the conn exists, we should not get another reservation.
	if nr := c.Reserve(ctx, oneep); nr != nil {
		t.Errorf("got %v, want nil", nr)
	}
	if nr := c.Reserve(ctx, nullep); nr != nil {
		t.Errorf("got %v, want nil", nr)
	}

	// Note that the context should not have been canceled.
	if err := r1.Context().Err(); err != nil {
		t.Errorf("got %v want nil", err)
	}

	pc := r2.ProxyConn()
	if pc == nil || pc.RemoteEndpoint().RoutingID != proxyep.RoutingID {
		t.Fatalf("got %v, want %v", pc.RemoteEndpoint(), proxyep)
	}
	twocaf := makeConnAndFlow(t, ctx, twoep)
	defer twocaf.stop(ctx)

	r2.Unreserve(twocaf.c, pc, nil)
}

func TestCacheFind(t *testing.T) {
	defer goroutines.NoLeaks(t, leakWaitTime)()
	ctx, shutdown := test.V23Init()
	defer shutdown()
	c := NewConnCache(0)

	ep, nullep, wprotoep, waddrep, waddrprotoep, resolvep := makeEPs(ctx, "address")

	auth := flowtest.NewPeerAuthorizer(ep.BlessingNames())
	caf := makeConnAndFlow(t, ctx, ep)
	defer caf.stop(ctx)
	conn := caf.c
	if err := c.Insert(conn, false); err != nil {
		t.Fatal(err)
	}
	// We should be able to find the conn in the cache.
	if got, _, _, err := c.Find(ctx, nullep, auth); err != nil || got != conn {
		t.Errorf("got %v, want %v, err: %v", got, conn, err)
	}
	// Changing the protocol should fail.
	if got, _, _, err := c.Find(ctx, wprotoep, auth); err == nil || got != nil {
		t.Errorf("got %v, want <nil>, err: %v", got, err)
	}
	// Changing the address should fail.
	if got, _, _, err := c.Find(ctx, waddrep, auth); err == nil || got != nil {
		t.Errorf("got %v, want <nil>, err: %v", got, err)
	}
	// Changing the blessingNames should fail.
	if got, _, _, err := c.Find(ctx, ep, flowtest.NewPeerAuthorizer([]string{"wrong"})); err == nil || got != nil {
		t.Errorf("got %v, want <nil>, err: %v", got, err)
	}
	// But finding a set of blessings that has at least one blessings in remote.Blessings should succeed.
	if got, _, _, err := c.Find(ctx, ep, flowtest.NewPeerAuthorizer([]string{"foo", ep.BlessingNames()[0]})); err != nil || got != conn {
		t.Errorf("got %v, want %v, err: %v", got, conn, err)
	}
	// Finding by routing ID should work.
	if got, _, _, err := c.Find(ctx, waddrprotoep, auth); err != nil || got != conn {
		t.Errorf("got %v, want %v, err: %v", got, conn, err)
	}
	// Finding by a valid resolve protocol and address should work.
	if got, _, _, err := c.Find(ctx, resolvep, auth); err != nil || got != conn {
		t.Errorf("got %v, want %v, err: %v", got, conn, err)
	}
	// Caching a proxied connection should not care about endpoint blessings, since the
	// blessings only correspond to the end server.
	proxyep, nullProxyep, _, _, _, _ := makeEPs(ctx, "proxy")
	caf = makeConnAndFlow(t, ctx, proxyep)
	defer caf.stop(ctx)
	proxyConn := caf.c
	if err := c.Insert(proxyConn, true); err != nil {
		t.Fatal(err)
	}
	// Wrong blessingNames should still work
	if got, _, _, err := c.Find(ctx, nullProxyep, flowtest.NewPeerAuthorizer([]string{"wrong"})); err != nil || got != proxyConn {
		t.Errorf("got %v, want %v, err: %v", got, proxyConn, err)
	}

	ridep, nullridep, _, _, waddrprotoridep, _ := makeEPs(ctx, "rid")

	// Caching with InsertWithRoutingID should only cache by RoutingID, not with network/address.
	ridauth := flowtest.NewPeerAuthorizer(ridep.BlessingNames())
	caf = makeConnAndFlow(t, ctx, ridep)
	defer caf.stop(ctx)
	ridConn := caf.c
	if err := c.InsertWithRoutingID(ridConn, false); err != nil {
		t.Fatal(err)
	}
	if got, _, _, err := c.Find(ctx, nullridep, ridauth); err == nil || got != nil {
		t.Errorf("got %v, want <nil>, err: %v", got, err)
	}
	// Finding by routing ID should work.
	if got, _, _, err := c.Find(ctx, waddrprotoridep, ridauth); err != nil || got != ridConn {
		t.Errorf("got %v, want %v, err: %v", got, ridConn, err)
	}

	// Insert a duplicate conn to ensure that replaced conns still get closed.
	caf = makeConnAndFlow(t, ctx, ep)
	defer caf.stop(ctx)
	dupConn := caf.c
	if err := c.Insert(dupConn, false); err != nil {
		t.Fatal(err)
	}

	// Closing the cache should close all the connections in the cache.
	// Ensure that the conns are not closed yet.
	if status := conn.Status(); status == connpackage.Closed {
		t.Fatal("wanted conn to not be closed")
	}
	if status := dupConn.Status(); status == connpackage.Closed {
		t.Fatal("wanted dupConn to not be closed")
	}
	c.Close(ctx)

	<-conn.Closed()
	<-ridConn.Closed()
	<-dupConn.Closed()
	<-proxyConn.Closed()
}

func TestLRU(t *testing.T) {
	defer goroutines.NoLeaks(t, leakWaitTime)()
	ctx, shutdown := test.V23Init()
	defer shutdown()

	// Ensure that the least recently created conns are killed by KillConnections.
	c := NewConnCache(0)
	conns, stop := nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	if err := c.KillConnections(ctx, 3); err != nil {
		t.Fatal(err)
	}
	// conns[3:] should not be closed and still in the cache.
	// conns[:3] should be closed and removed from the cache.
	for _, conn := range conns[3:] {
		if status := conn.c.Status(); status == connpackage.Closed {
			t.Errorf("conn %v should not have been closed", conn)
		}
		if !isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v(%p) should still be in cache:\n%s",
				conn.c.RemoteEndpoint(), conn.c, c)
		}
	}
	for _, conn := range conns[:3] {
		<-conn.c.Closed()
		if isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v should not be in cache", conn)
		}
	}

	// Ensure that writing to conns marks conns as more recently used.
	c = NewConnCache(0)
	conns, stop = nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	for _, conn := range conns[:7] {
		conn.write()
	}
	if err := c.KillConnections(ctx, 3); err != nil {
		t.Fatal(err)
	}
	// conns[:7] should not be closed and still in the cache.
	// conns[7:] should be closed and removed from the cache.
	for _, conn := range conns[:7] {
		if status := conn.c.Status(); status == connpackage.Closed {
			t.Errorf("conn %v should not have been closed", conn)
		}
		if !isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v should still be in cache", conn)
		}
	}
	for _, conn := range conns[7:] {
		<-conn.c.Closed()
		if isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v should not be in cache", conn)
		}
	}

	// Ensure that reading from conns marks conns as more recently used.
	c = NewConnCache(0)
	conns, stop = nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	for _, conn := range conns[:7] {
		conn.read()
	}
	if err := c.KillConnections(ctx, 3); err != nil {
		t.Fatal(err)
	}
	// conns[:7] should not be closed and still in the cache.
	// conns[7:] should be closed and removed from the cache.
	for _, conn := range conns[:7] {
		if status := conn.c.Status(); status == connpackage.Closed {
			t.Errorf("conn %v should not have been closed", conn)
		}
		if !isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v(%p) should still be in cache:\n%s",
				conn.c.RemoteEndpoint(), conn.c, c)
		}
	}
	for _, conn := range conns[7:] {
		<-conn.c.Closed()
		if isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v should not be in cache", conn)
		}
	}
}

func TestIdleConns(t *testing.T) {
	defer goroutines.NoLeaks(t, leakWaitTime)()
	ctx, shutdown := test.V23Init()
	defer shutdown()

	// Ensure that idle conns are killed by the cache.
	// Set the idle timeout very low to ensure all the connections are closed.
	c := NewConnCache(1)
	conns, stop := nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		// close the flows so the conns aren't kept alive due to ongoing flows.
		conn.f.Close()
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	time.Sleep(2 * time.Millisecond)
	if err := c.KillConnections(ctx, 0); err != nil {
		t.Fatal(err)
	}
	// All connections should be lameducked.
	for _, conn := range conns {
		if status := conn.c.Status(); status < connpackage.EnteringLameDuck {
			t.Errorf("conn %v should have been lameducked", conn)
		}
	}
	// We wait for the acknowledgement of the lameduck, then KillConnections should
	// actually close the connections.
	for _, conn := range conns {
		<-conn.c.EnterLameDuck(ctx)
	}
	if err := c.KillConnections(ctx, 0); err != nil {
		t.Fatal(err)
	}
	// All connections should be removed from the cache.
	for _, conn := range conns {
		<-conn.c.Closed()
		if isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v should not be in cache", conn)
		}
	}

	// Set the idle timeout very high to ensure none of the connections are closed.
	c = NewConnCache(time.Hour)
	conns, stop = nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		// close the flows so the conns aren't kept alive due to ongoing flows.
		conn.f.Close()
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	if err := c.KillConnections(ctx, 0); err != nil {
		t.Fatal(err)
	}
	for _, conn := range conns {
		if status := conn.c.Status(); status >= connpackage.EnteringLameDuck {
			t.Errorf("conn %v should not have been closed or lameducked", conn)
		}
		if !isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v(%p) should still be in cache:\n%s",
				conn.c.RemoteEndpoint(), conn.c, c)
		}
	}

	// Ensure that a low idle timeout, but live flows on the conns keep the connection alive.
	c = NewConnCache(1)
	conns, stop = nConnAndFlows(t, ctx, 10)
	defer stop()
	for _, conn := range conns {
		// don't close the flows so that the conns are kept alive.
		if err := c.Insert(conn.c, false); err != nil {
			t.Fatal(err)
		}
	}
	if err := c.KillConnections(ctx, 0); err != nil {
		t.Fatal(err)
	}
	for _, conn := range conns {
		if status := conn.c.Status(); status >= connpackage.LameDuckAcknowledged {
			t.Errorf("conn %v should not have been closed or lameducked", conn)
		}
		if !isInCache(ctx, c, conn.c) {
			t.Errorf("conn %v(%p) should still be in cache:\n%s",
				conn.c.RemoteEndpoint(), conn.c, c)
		}
	}
}

func TestMultiRTTConns(t *testing.T) {
	defer goroutines.NoLeaks(t, leakWaitTime)()
	ctx, shutdown := test.V23Init()
	defer shutdown()

	c := NewConnCache(0)
	remote, _, _, _, _, _ := makeEPs(ctx, "normal")
	auth := flowtest.NewPeerAuthorizer(remote.BlessingNames())
	slow, med, fast := 3*time.Millisecond, 2*time.Millisecond, 1*time.Millisecond
	// Add a slow connection into the cache and ensure it is found.
	slowConn := newRTTConn(ctx, remote, slow)
	if err := c.Insert(slowConn, false); err != nil {
		t.Fatal(err)
	}
	if got, _, _, err := c.Find(ctx, remote, auth); err != nil || got != slowConn {
		t.Errorf("got %v, want %v, err: %v", got, slowConn, err)
	}

	// Add a fast connection into the cache and ensure it is found over the slow one.
	fastConn := newRTTConn(ctx, remote, fast)
	if err := c.Insert(fastConn, false); err != nil {
		t.Fatal(err)
	}
	if got, _, _, err := c.Find(ctx, remote, auth); err != nil || got != fastConn {
		t.Errorf("got %v, want %v, err: %v", got, fastConn, err)
	}

	// Add a med connection into the cache and ensure that the fast one is still found.
	medConn := newRTTConn(ctx, remote, med)
	if err := c.Insert(medConn, false); err != nil {
		t.Fatal(err)
	}
	if got, _, _, err := c.Find(ctx, remote, auth); err != nil || got != fastConn {
		t.Errorf("got %v, want %v, err: %v", got, fastConn, err)
	}

	// Kill the fast connection and ensure the med connection is found.
	fastConn.Close(ctx, nil)
	if got, _, _, err := c.Find(ctx, remote, auth); err != nil || got != medConn {
		t.Errorf("got %v, want %v, err: %v", got, medConn, err)
	}
}

func newRTTConn(ctx *context.T, ep naming.Endpoint, rtt time.Duration) *rttConn {
	return &rttConn{
		ctx:    ctx,
		ep:     ep,
		rtt:    rtt,
		closed: make(chan struct{}),
	}
}

type rttConn struct {
	ctx    *context.T
	ep     naming.Endpoint
	rtt    time.Duration
	closed chan struct{}
}

func (c *rttConn) Status() connpackage.Status {
	select {
	case <-c.closed:
		return connpackage.Closed
	default:
		return connpackage.Active
	}
}
func (c *rttConn) IsEncapsulated() bool                  { return false }
func (c *rttConn) IsIdle(*context.T, time.Duration) bool { return false }
func (c *rttConn) EnterLameDuck(*context.T) chan struct{} {
	ch := make(chan struct{})
	close(ch)
	return ch
}
func (c *rttConn) RemoteLameDuck() bool                       { return false }
func (c *rttConn) CloseIfIdle(*context.T, time.Duration) bool { return false }
func (c *rttConn) Close(*context.T, error) {
	select {
	case <-c.closed:
	default:
		close(c.closed)
	}
}
func (c *rttConn) RemoteEndpoint() naming.Endpoint { return c.ep }
func (c *rttConn) LocalEndpoint() naming.Endpoint  { return c.ep }
func (c *rttConn) RemoteBlessings() security.Blessings {
	b, _ := v23.GetPrincipal(c.ctx).BlessingStore().Default()
	return b
}
func (c *rttConn) RemoteDischarges() map[string]security.Discharge { return nil }
func (c *rttConn) RTT() time.Duration                              { return c.rtt }
func (c *rttConn) LastUsed() time.Time                             { return time.Now() }
func (c *rttConn) DebugString() string                             { return "" }

func isInCache(ctx *context.T, c *ConnCache, conn *connpackage.Conn) bool {
	rep := conn.RemoteEndpoint()
	_, _, _, err := c.Find(ctx, rep, flowtest.NewPeerAuthorizer(rep.BlessingNames()))
	return err == nil
}

type connAndFlow struct {
	c *connpackage.Conn
	a *connpackage.Conn
	f flow.Flow
}

func (c connAndFlow) write() {
	_, err := c.f.WriteMsg([]byte{0})
	if err != nil {
		panic(err)
	}
}

func (c connAndFlow) read() {
	_, err := c.f.ReadMsg()
	if err != nil {
		panic(err)
	}
}

func (c connAndFlow) stop(ctx *context.T) {
	c.c.Close(ctx, nil)
	c.a.Close(ctx, nil)
}

func nConnAndFlows(t *testing.T, ctx *context.T, n int) ([]connAndFlow, func()) {
	cfs := make([]connAndFlow, n)
	for i := 0; i < n; i++ {
		cfs[i] = makeConnAndFlow(t, ctx, naming.Endpoint{
			Protocol:  "local",
			Address:   strconv.Itoa(i),
			RoutingID: naming.FixedRoutingID(uint64(i + 1)), // We need to have a nonzero rid for bidi.
		})
	}
	return cfs, func() {
		for _, conn := range cfs {
			conn.stop(ctx)
		}
	}
}

func makeConnAndFlow(t *testing.T, ctx *context.T, ep naming.Endpoint) connAndFlow {
	dmrw, amrw := flowtest.Pipe(t, ctx, "local", "")
	dch := make(chan *connpackage.Conn)
	ach := make(chan *connpackage.Conn)
	go func() {
		d, _, _, err := connpackage.NewDialed(ctx, dmrw, ep, ep,
			version.RPCVersionRange{Min: 1, Max: 5},
			flowtest.AllowAllPeersAuthorizer{},
			time.Minute, 0, nil)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
		dch <- d
	}()
	fh := fh{t, make(chan struct{})}
	go func() {
		a, err := connpackage.NewAccepted(ctx, nil, amrw, ep,
			version.RPCVersionRange{Min: 1, Max: 5}, time.Minute, 0, fh)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
		ach <- a
	}()
	conn := <-dch
	aconn := <-ach
	f, err := conn.Dial(ctx, conn.LocalBlessings(), nil, conn.RemoteEndpoint(), 0, false)
	if err != nil {
		t.Fatal(err)
	}
	// Write a byte to send the openFlow message.
	if _, err := f.Write([]byte{0}); err != nil {
		t.Fatal(err)
	}
	<-fh.ch
	return connAndFlow{conn, aconn, f}
}

type fh struct {
	t  *testing.T
	ch chan struct{}
}

func (h fh) HandleFlow(f flow.Flow) error {
	go func() {
		if _, err := f.WriteMsg([]byte{0}); err != nil {
			h.t.Errorf("failed to write: %v", err)
		}
		close(h.ch)
	}()
	return nil
}

func unionBlessing(ctx *context.T, names ...string) []string {
	principal := v23.GetPrincipal(ctx)
	blessings := make([]security.Blessings, len(names))
	for i, name := range names {
		var err error
		if blessings[i], err = principal.BlessSelf(name); err != nil {
			panic(err)
		}
	}
	union, err := security.UnionOfBlessings(blessings...)
	if err != nil {
		panic(err)
	}
	if err := security.AddToRoots(principal, union); err != nil {
		panic(err)
	}
	if err := principal.BlessingStore().SetDefault(union); err != nil {
		panic(err)
	}
	return security.BlessingNames(principal, union)
}

// resolveProtocol returns a fixed protocol and addresses for its Resolve function.
type resolveProtocol struct {
	protocol  string
	addresses []string
}

func (p *resolveProtocol) Resolve(_ *context.T, _, _ string) (string, []string, error) {
	return p.protocol, p.addresses, nil
}
func (*resolveProtocol) Dial(_ *context.T, _, _ string, _ time.Duration) (flow.Conn, error) {
	return nil, nil
}
func (*resolveProtocol) Listen(_ *context.T, _, _ string) (flow.Listener, error) {
	return nil, nil
}
