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

import (
	"fmt"
	"reflect"
	"runtime"
	"testing"
	"time"

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

	ldiscovery "v.io/x/ref/lib/discovery"
	"v.io/x/ref/lib/discovery/plugins/mock"
)

func TestBasic(t *testing.T) {
	ds := ldiscovery.New([]ldiscovery.Plugin{mock.New()})
	services := []discovery.Service{
		{
			InstanceUuid:  ldiscovery.NewInstanceUUID(),
			InterfaceName: "v.io/v23/a",
			Addrs:         []string{"/h1:123/x", "/h2:123/y"},
		},
		{
			InstanceUuid:  ldiscovery.NewInstanceUUID(),
			InterfaceName: "v.io/v23/b",
			Addrs:         []string{"/h1:123/x", "/h2:123/z"},
		},
	}
	var stops []func()
	for _, service := range services {
		stop, err := advertise(ds, service)
		if err != nil {
			t.Fatal(err)
		}
		stops = append(stops, stop)
	}

	// Make sure all advertisements are discovered.
	if err := scanAndMatch(ds, "v.io/v23/a", services[0]); err != nil {
		t.Error(err)
	}
	if err := scanAndMatch(ds, "v.io/v23/b", services[1]); err != nil {
		t.Error(err)
	}
	if err := scanAndMatch(ds, "", services...); err != nil {
		t.Error(err)
	}
	if err := scanAndMatch(ds, "v.io/v23/c"); err != nil {
		t.Error(err)
	}

	// Open a new scan channel and consume expected advertisements first.
	scan, scanStop, err := startScan(ds, "v.io/v23/a")
	if err != nil {
		t.Error(err)
	}
	defer scanStop()
	update := <-scan
	if !matchFound([]discovery.Update{update}, services[0]) {
		t.Errorf("Unexpected scan: %v", update)
	}

	// Make sure scan returns the lost advertisement when advertising is stopped.
	stops[0]()

	update = <-scan
	if !matchLost([]discovery.Update{update}, services[0]) {
		t.Errorf("Unexpected scan: %v", update)
	}

	// Also it shouldn't affect the other.
	if err := scanAndMatch(ds, "v.io/v23/b", services[1]); err != nil {
		t.Error(err)
	}

	// Stop advertising the remaining one; Shouldn't discover any service.
	stops[1]()
	if err := scanAndMatch(ds, ""); err != nil {
		t.Error(err)
	}
}

func advertise(ds discovery.Advertiser, services ...discovery.Service) (func(), error) {
	ctx, cancel := context.RootContext()
	for _, service := range services {
		if err := ds.Advertise(ctx, service, nil); err != nil {
			return nil, fmt.Errorf("Advertise failed: %v", err)
		}
	}
	return cancel, nil
}

func startScan(ds discovery.Scanner, query string) (<-chan discovery.Update, func(), error) {
	ctx, stop := context.RootContext()
	scan, err := ds.Scan(ctx, query)
	if err != nil {
		return nil, nil, fmt.Errorf("Scan failed: %v", err)
	}
	return scan, stop, err
}

func scan(ds discovery.Scanner, query string) ([]discovery.Update, error) {
	scan, stop, err := startScan(ds, query)
	if err != nil {
		return nil, err
	}
	defer stop()

	var updates []discovery.Update
	for {
		select {
		case update := <-scan:
			updates = append(updates, update)
		case <-time.After(5 * time.Millisecond):
			return updates, nil
		}
	}
}

func match(updates []discovery.Update, lost bool, wants ...discovery.Service) bool {
	for _, want := range wants {
		matched := false
		for i, update := range updates {
			var service discovery.Service
			switch u := update.(type) {
			case discovery.UpdateFound:
				if !lost {
					service = u.Value.Service
				}
			case discovery.UpdateLost:
				if lost {
					service = u.Value.Service
				}
			}
			matched = reflect.DeepEqual(service, want)
			if matched {
				updates = append(updates[:i], updates[i+1:]...)
				break
			}
		}
		if !matched {
			return false
		}
	}
	return len(updates) == 0
}

func matchFound(updates []discovery.Update, wants ...discovery.Service) bool {
	return match(updates, false, wants...)
}

func matchLost(updates []discovery.Update, wants ...discovery.Service) bool {
	return match(updates, true, wants...)
}

func scanAndMatch(ds discovery.Scanner, query string, wants ...discovery.Service) error {
	const timeout = 3 * time.Second

	var updates []discovery.Update
	for now := time.Now(); time.Since(now) < timeout; {
		runtime.Gosched()

		var err error
		updates, err = scan(ds, query)
		if err != nil {
			return err
		}
		if matchFound(updates, wants...) {
			return nil
		}
	}
	return fmt.Errorf("Match failed; got %v, but wanted %v", updates, wants)
}
