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

import (
	"reflect"
	"sync"
	"testing"

	"third_party/go/tool/android_arm/src/fmt"

	mojom "mojom/vanadium/discovery"

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

	idiscovery "v.io/x/ref/lib/discovery"
	_ "v.io/x/ref/runtime/factories/generic"
	vtest "v.io/x/ref/test"
)

type mockAdv struct {
	s discovery.Service
}

type discoveryMock struct {
	mu       sync.Mutex
	trigger  *idiscovery.Trigger
	id       int64
	services map[int64]discovery.Service
	// An item will be put in deleteCh when something has been deleted.
	deleteCh chan struct{}
}

func (d *discoveryMock) Advertise(ctx *context.T, s discovery.Service, perms []security.BlessingPattern) (<-chan struct{}, error) {
	d.mu.Lock()
	currId := d.id
	d.services[currId] = s
	d.id++
	d.mu.Unlock()
	done := make(chan struct{})
	stop := func() {
		d.mu.Lock()
		delete(d.services, currId)
		d.mu.Unlock()
		close(done)

		go func() { d.deleteCh <- struct{}{} }()
	}
	d.trigger.Add(stop, ctx.Done())
	return done, nil
}

func (*discoveryMock) Scan(ctx *context.T, query string) (<-chan discovery.Update, error) {
	return nil, nil
}

func (*discoveryMock) Close() {}

func compare(want discovery.Service, got mojom.Service) error {
	mwant := v2mService(want)
	if !reflect.DeepEqual(mwant, got) {
		return fmt.Errorf("Got %#v want %#v", got, want)
	}
	return nil
}

func TestAdvertising(t *testing.T) {
	ctx, shutdown := vtest.V23Init()
	defer shutdown()
	mock := &discoveryMock{
		trigger:  idiscovery.NewTrigger(),
		services: map[int64]discovery.Service{},
		deleteCh: make(chan struct{}),
	}
	s := NewDiscoveryService(ctx, mock)
	testService := mojom.Service{
		InterfaceName: "v.io/v23/discovery.T",
		Attrs: map[string]string{
			"key1": "value1",
			"key2": "value2",
		},
		Addrs: []string{"addr1", "addr2"},
	}
	id, e1, e2 := s.Advertise(testService, nil)

	if e1 != nil || e2 != nil {
		t.Fatalf("Failed to start service: %v, %v", e1, e2)
	}
	if len(mock.services) != 1 {
		t.Errorf("service missing in mock")
	}

	for _, service := range mock.services {
		if err := compare(service, testService); err != nil {
			t.Error(err)
		}

	}

	testService2 := mojom.Service{
		InterfaceName: "v.io/v23/naming.T",
		Attrs: map[string]string{
			"key1": "value1",
			"key2": "value2",
		},
		Addrs: []string{"addr1", "addr2"},
	}

	_, e1, e2 = s.Advertise(testService2, nil)
	if e1 != nil || e2 != nil {
		t.Fatalf("Failed to start service: %v, %v", e1, e2)
	}

	s.Stop(id)
	// Wait for the deletion to finish.
	<-mock.deleteCh
	if len(mock.services) != 1 {
		t.Errorf("service should have been removed")
	}

	for _, service := range mock.services {
		if err := compare(service, testService2); err != nil {
			t.Error(err)
		}

	}

	s.StopAll()
	<-mock.deleteCh
	if len(mock.services) != 0 {
		t.Errorf("service should have been removed")
	}
}
