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

import (
	"bytes"
	"reflect"
	"testing"

	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/rpc"
	"v.io/v23/security"

	idiscovery "v.io/x/ref/lib/discovery"
	"v.io/x/ref/lib/discovery/plugins/mock"
	"v.io/x/ref/lib/discovery/testutil"
	"v.io/x/ref/runtime/factories/fake"
	"v.io/x/ref/test"
)

func TestDirectoryBasic(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	var dirServer idiscovery.DirectoryServerStub

	mockServer := testutil.NewMockServer(testutil.ToEndpoints("addr:123"))
	ctx = fake.SetServerFactory(ctx, func(_ *context.T, _ string, impl interface{}, _ security.Authorizer, _ ...rpc.ServerOpt) (*context.T, rpc.Server) {
		dirServer = impl.(idiscovery.DirectoryServerStub)
		return ctx, mockServer
	})

	df, err := idiscovery.NewFactory(ctx, mock.New())
	if err != nil {
		t.Fatal(err)
	}
	defer df.Shutdown()

	ad := discovery.Advertisement{
		InterfaceName: "v.io/v23/a",
		Addresses:     []string{"/h1:123/x"},
		Attachments:   discovery.Attachments{"a": []byte{1, 2, 3}},
	}

	d1, err := df.New(ctx)
	if err != nil {
		t.Fatal(err)
	}

	stop, err := testutil.Advertise(ctx, d1, nil, &ad)
	if err != nil {
		t.Fatal(err)
	}

	// The directory server should serve the advertisement.
	fetched, err := dirServer.Lookup(ctx, nil, ad.Id)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(fetched.Ad, ad) {
		t.Errorf("got %v, but wanted %v", fetched.Ad, ad)
	}

	attachment, err := dirServer.GetAttachment(ctx, nil, ad.Id, "a")
	if err != nil {
		t.Fatal(err)
	}
	if !bytes.Equal(attachment, ad.Attachments["a"]) {
		t.Errorf("got %v, but wanted %v", attachment, ad.Attachments["a"])
	}

	attachment, err = dirServer.GetAttachment(ctx, nil, ad.Id, "b")
	if err != nil {
		t.Fatal(err)
	}
	if attachment != nil {
		t.Errorf("got %v, but wanted %v", attachment, nil)
	}

	// Stop advertising; Shouldn't be served by the directory server.
	stop()

	if _, err = dirServer.Lookup(ctx, nil, ad.Id); err == nil {
		t.Error("expected an error, but got none")
	}
	if _, err = dirServer.GetAttachment(ctx, nil, ad.Id, "a"); err == nil {
		t.Error("expected an error, but got none")
	}
}

func TestDirectoryRoaming(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	var dirServer idiscovery.DirectoryServerStub

	eps := testutil.ToEndpoints("addr:123")
	mockServer := testutil.NewMockServer(eps)
	ctx = fake.SetServerFactory(ctx, func(_ *context.T, _ string, impl interface{}, _ security.Authorizer, _ ...rpc.ServerOpt) (*context.T, rpc.Server) {
		dirServer = impl.(idiscovery.DirectoryServerStub)
		return ctx, mockServer
	})

	mockPlugin := mock.NewWithAdStatus(idiscovery.AdPartiallyReady)
	df, err := idiscovery.NewFactory(ctx, mockPlugin)
	if err != nil {
		t.Fatal(err)
	}
	defer df.Shutdown()

	ad := discovery.Advertisement{
		InterfaceName: "v.io/v23/a",
		Addresses:     []string{"/h1:123/x"},
	}

	d1, err := df.New(ctx)
	if err != nil {
		t.Fatal(err)
	}

	stop, err := testutil.Advertise(ctx, d1, nil, &ad)
	if err != nil {
		t.Fatal(err)
	}
	defer stop()

	d2, err := df.New(ctx)
	if err != nil {
		t.Fatal(err)
	}

	// Open a new scan channel and consume expected advertisements first.
	scanCh, scanStop, err := testutil.Scan(ctx, d2, ``)
	if err != nil {
		t.Fatal(err)
	}
	defer scanStop()

	update := <-scanCh
	if !testutil.MatchFound(ctx, []discovery.Update{update}, ad) {
		t.Errorf("unexpected scan: %v", update)
	}

	fetched, err := dirServer.Lookup(ctx, nil, ad.Id)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(testutil.ToEndpoints(fetched.DirAddrs...), eps) {
		t.Errorf("got %v, but wanted %v", testutil.ToEndpoints(fetched.DirAddrs...), eps)
	}

	updateCh := make(chan *idiscovery.AdInfo)
	callback := func(ad *idiscovery.AdInfo) {
		select {
		case updateCh <- ad:
		case <-ctx.Done():
		}
	}
	if err = mockPlugin.Scan(ctx, "", callback, func() {}); err != nil {
		t.Fatal(err)
	}
	<-updateCh

	eps = testutil.ToEndpoints("addr:456")
	mockServer.UpdateNetwork(eps)

	// Wait until the address change is applied
	for {
		adinfo := <-updateCh
		if reflect.DeepEqual(testutil.ToEndpoints(adinfo.DirAddrs...), eps) {
			break
		}
	}

	// Make sure that a new advertisement is published.
	update = <-scanCh
	if !testutil.MatchLost(ctx, []discovery.Update{update}, ad) {
		t.Errorf("unexpected scan: %v", update)
	}
	update = <-scanCh
	if !testutil.MatchFound(ctx, []discovery.Update{update}, ad) {
		t.Errorf("unexpected scan: %v", update)
	}

	fetched, err = dirServer.Lookup(ctx, nil, ad.Id)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(testutil.ToEndpoints(fetched.DirAddrs...), eps) {
		t.Errorf("got %v, but wanted %v", testutil.ToEndpoints(fetched.DirAddrs...), eps)
	}
}
