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

import (
	"fmt"
	"os"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/options"
	"v.io/x/lib/gosh"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/lib/v23test"
	"v.io/x/ref/services/mounttable/mounttablelib"
)

// TODO(sadovsky): Switch to using v23test.Shell.StartRootMountTable.
var rootMT = gosh.Register("rootMT", func() error {
	ctx, shutdown := v23.Init()
	defer shutdown()

	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
	if err != nil {
		return fmt.Errorf("mounttable.NewMountTableDispatcher failed: %s", err)
	}
	_, server, err := v23.WithNewDispatchingServer(ctx, "", mt, options.ServesMountTable(true))
	if err != nil {
		return fmt.Errorf("root failed: %v", err)
	}
	fmt.Printf("PID=%d\n", os.Getpid())
	for _, ep := range server.Status().Endpoints {
		fmt.Printf("MT_NAME=%s\n", ep.Name())
	}
	<-signals.ShutdownOnSignals(ctx)
	return nil
})

// Asserts that the channel contains members with expected names and no others.
func AssertMembersWithNames(channel *channel, expectedNames []string, retry bool) error {

	waitForN := func(expected int) ([]*member, error) {
		deadline := time.Now().Add(5 * time.Minute)
		for {
			members, err := channel.getMembers()
			if err != nil || len(members) != expected {
				if retry {
					if time.Now().After(deadline) {
						return nil, fmt.Errorf("timed out expecting %d members", expected)
					}
					time.Sleep(10 * time.Millisecond)
					continue
				}
				if err != nil {
					return nil, fmt.Errorf("channel.getMembers() failed: %v", err)
				}
				return nil, fmt.Errorf("Wrong number of members.  Expected %v, actual %v.", len(members), expected)
			}
			return members, nil
		}
	}

	members, err := waitForN(len(expectedNames))
	if err != nil {
		return err
	}

	for _, expectedName := range expectedNames {
		found := false
		for _, member := range members {
			if member.Name == expectedName {
				found = true
				break
			}
		}
		if !found {
			return fmt.Errorf("Expected member with name %v, but did not find one.", expectedName)
		}
	}
	return nil
}

func TestMembers(t *testing.T) {
	sh := v23test.NewShell(t, v23test.Opts{})
	defer sh.Cleanup()
	ctx := sh.Ctx

	c := sh.Fn(rootMT)
	c.Args = append(c.Args, "--v23.tcp.address=127.0.0.1:0")
	c.Start()
	c.S.ExpectVar("PID")
	mounttable := c.S.ExpectVar("MT_NAME")

	proxy := ""
	path := "path/to/channel"

	// Create a new channel.
	channel, err := newChannel(ctx, mounttable, proxy, path)
	if err != nil {
		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
	}

	// New channel should be empty.
	if err := AssertMembersWithNames(channel, []string{}, false); err != nil {
		t.Error(err)
	}

	// Join the channel.
	if err := channel.join(); err != nil {
		t.Fatalf("channel.join() failed: %v", err)
	}

	// Channel should contain only current user.
	if err := AssertMembersWithNames(channel, []string{channel.UserName()}, true); err != nil {
		t.Error(err)
	}

	// Create and join the channel a second time.
	channel2, err := newChannel(ctx, mounttable, proxy, path)
	if err != nil {
		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
	}
	if err := channel2.join(); err != nil {
		t.Fatalf("channel2.join() failed: %v", err)
	}

	// Channel should contain both users.
	if err := AssertMembersWithNames(channel, []string{channel.UserName(), channel2.UserName()}, true); err != nil {
		t.Error(err)
	}

	// Leave first instance of channel.
	if err := channel.leave(); err != nil {
		t.Fatalf("channel.leave() failed: %v", err)
	}

	// Channel should contain only second user.
	if err := AssertMembersWithNames(channel, []string{channel2.UserName()}, true); err != nil {
		t.Error(err)
	}

	// Leave second instance of channel.
	if err := channel2.leave(); err != nil {
		t.Fatalf("channel2.leave() failed: %v", err)
	}

	// Channel should be empty.
	if err := AssertMembersWithNames(channel, []string{}, true); err != nil {
		t.Error(err)
	}
}

func TestBroadcastMessage(t *testing.T) {
	sh := v23test.NewShell(t, v23test.Opts{})
	defer sh.Cleanup()
	ctx := sh.Ctx

	c := sh.Fn(rootMT)
	c.Args = append(c.Args, "--v23.tcp.address=127.0.0.1:0")
	c.Start()
	c.S.ExpectVar("PID")
	mounttable := c.S.ExpectVar("MT_NAME")

	proxy := ""
	path := "path/to/channel"

	channel, err := newChannel(ctx, mounttable, proxy, path)
	if err != nil {
		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
	}

	defer channel.leave()

	if err := channel.join(); err != nil {
		t.Fatalf("channel.join() failed: %v", err)
	}

	message := "Hello Vanadium world!"

	go func() {
		// Call getMembers(), which will set channel.members, used by
		// channel.broadcastMessage().
		deadline := time.Now().Add(time.Minute)
		for {
			m, err := channel.getMembers()
			if err != nil {
				t.Fatalf("channel.getMembers() failed: %v", err)
			}
			if len(m) > 0 {
				break
			}
			if time.Now().After(deadline) {
				t.Fatalf("channel.getMembers: timed out getting a member")
			}
			time.Sleep(10 * time.Millisecond)
		}
		if err := channel.broadcastMessage(message); err != nil {
			t.Fatalf("channel.broadcastMessage(%v) failed: %v", message, err)
		}
	}()

	select {
	case <-time.After(10 * time.Second):
		t.Errorf("Timeout waiting for message to be received.")
	case m := <-channel.messages:
		if m.Text != message {
			t.Errorf("Expected message text to be %v but got %v", message, m.Text)
		}
		if got, want := m.SenderName, channel.UserName(); got != want {
			t.Errorf("Got m.SenderName = %v, want %v", got, want)
		}
	}
}

func TestMain(m *testing.M) {
	os.Exit(v23test.Run(m.Run))
}
