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

import (
	"errors"
	"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"
	securitylib "v.io/x/ref/lib/security"
	"v.io/x/ref/runtime/internal/flow/flowtest"
)

type fh chan<- flow.Flow

func (fh fh) HandleFlow(f flow.Flow) error {
	if fh == nil {
		panic("writing to nil flow handler")
	}
	fh <- f
	return nil
}

func setupConns(t *testing.T,
	network, address string,
	dctx, actx *context.T,
	dflows, aflows chan<- flow.Flow,
	dAuth, aAuth []security.BlessingPattern) (dialed, accepted *Conn, derr, aerr error) {
	dmrw, amrw := flowtest.Pipe(t, actx, network, address)
	versions := version.RPCVersionRange{Min: 3, Max: 5}
	ridep, err := v23.NewEndpoint("@6@@batman.com:1234@@000000000000000000000000dabbad00@m@@@")
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	ep, err := v23.NewEndpoint("localhost:80")
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	dch := make(chan *Conn)
	ach := make(chan *Conn)
	derrch := make(chan error)
	aerrch := make(chan error)
	go func() {
		var handler FlowHandler
		dep := ep
		if dflows != nil {
			handler = fh(dflows)
			dep = ridep
		}
		dBlessings := v23.GetPrincipal(dctx).BlessingStore().Default()
		d, err := NewDialed(dctx, dBlessings, dmrw, dep, ep, versions, peerAuthorizer{dBlessings, dAuth}, time.Minute, 0, handler)
		dch <- d
		derrch <- err
	}()
	go func() {
		var handler FlowHandler
		if aflows != nil {
			handler = fh(aflows)
		}
		aBlessings := v23.GetPrincipal(actx).BlessingStore().Default()
		a, err := NewAccepted(actx, aBlessings, aAuth, amrw, ridep, versions, time.Minute, 0, handler)
		ach <- a
		aerrch <- err
	}()
	return <-dch, <-ach, <-derrch, <-aerrch
}

func setupFlow(t *testing.T, network, address string, dctx, actx *context.T, dialFromDialer bool) (dialed flow.Flow, accepted <-chan flow.Flow, close func()) {
	dfs, accepted, ac, dc := setupFlows(t, network, address, dctx, actx, dialFromDialer, 1)
	return dfs[0], accepted, func() { dc.Close(dctx, nil); ac.Close(dctx, nil) }
}

func setupFlows(t *testing.T, network, address string, dctx, actx *context.T, dialFromDialer bool, n int) (dialed []flow.Flow, accepted <-chan flow.Flow, dc, ac *Conn) {
	dialed = make([]flow.Flow, n)
	dflows, aflows := make(chan flow.Flow, n), make(chan flow.Flow, n)
	d, a, derr, aerr := setupConns(t, network, address, dctx, actx, dflows, aflows, nil, nil)
	if derr != nil || aerr != nil {
		t.Fatal(derr, aerr)
	}
	if !dialFromDialer {
		d, a = a, d
		dctx, actx = actx, dctx
		aflows, dflows = dflows, aflows
	}
	for i := 0; i < n; i++ {
		var err error
		if dialed[i], err = d.Dial(dctx, flowtest.AllowAllPeersAuthorizer{}, nil, 0); err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}
	}
	return dialed, aflows, d, a
}

type peerAuthorizer struct {
	// blessings are the blessings presented to all peers.
	blessings security.Blessings
	// authorizedPeers are the set of blessing patterns according
	// to which peers are authorized. If the set is nil or empty then
	// all peers are authorized.
	authorizedPeers []security.BlessingPattern
}

func (a peerAuthorizer) AuthorizePeer(
	ctx *context.T,
	localEP, remoteEP naming.Endpoint,
	remoteBlessings security.Blessings,
	remoteDischarges map[string]security.Discharge,
) ([]string, []security.RejectedBlessing, error) {
	call := security.NewCall(&security.CallParams{
		Timestamp:        time.Now(),
		LocalPrincipal:   v23.GetPrincipal(ctx),
		LocalEndpoint:    localEP,
		RemoteEndpoint:   remoteEP,
		RemoteBlessings:  remoteBlessings,
		RemoteDischarges: remoteDischarges,
	})
	peerNames, rejectedNames := security.RemoteBlessingNames(ctx, call)
	if len(a.authorizedPeers) == 0 {
		return peerNames, rejectedNames, nil
	}
	for _, p := range a.authorizedPeers {
		if p.MatchedBy(peerNames...) {
			return peerNames, rejectedNames, nil
		}
	}
	return nil, nil, errors.New("peer not authorized")
}

func (a peerAuthorizer) BlessingsForPeer(ctx *context.T, _ []string) (
	security.Blessings, map[string]security.Discharge, error) {
	dis, _ := securitylib.PrepareDischarges(ctx, a.blessings, security.DischargeImpetus{})
	return a.blessings, dis, nil
}
