package lib

import (
	"reflect"
	"testing"

	mocks_ipc "veyron/runtimes/google/testing/mocks/ipc"
	"veyron2/ipc"
	"veyron2/rt"
	"veyron2/vdl/vdlutil"
	"veyron2/wiretype"
)

const (
	name = "/veyron/name"
)

func init() {
	rt.Init()
}

func expectedSignature() ipc.ServiceSignature {
	return ipc.ServiceSignature{
		Methods: make(map[string]ipc.MethodSignature),
		TypeDefs: []vdlutil.Any{
			wiretype.NamedPrimitiveType{
				Name: "veyron2/vdlutil.AnyData",
				Type: wiretype.TypeIDInterface,
			},
		},
	}
}

func client() *mocks_ipc.SimpleMockClient {
	return mocks_ipc.NewSimpleClient(
		map[string][]interface{}{
			"Signature": []interface{}{expectedSignature(), nil},
		},
	)
}

func assertMethodSignatureAsExpected(t *testing.T, got, expected ipc.MethodSignature) {
	if !reflect.DeepEqual(got.InArgs, expected.InArgs) {
		t.Errorf(`InArgs do not match: result "%v", want "%v"`, got.InArgs, expected.InArgs)
		return
	}
	if !reflect.DeepEqual(got.OutArgs, expected.OutArgs) {
		t.Errorf(`OutArgs do not match: result "%v", want "%v"`, got.OutArgs, expected.OutArgs)
		return
	}
	if got.InStream != expected.InStream {
		t.Errorf(`InStreams do not match: result "%v", want "%v"`, got.InStream, expected.InStream)
		return
	}
	if got.OutStream != expected.OutStream {
		t.Errorf(`OutStream do not match: result "%v", want "%v"`, got.OutStream, expected.OutStream)
		return
	}
}

func assertSignatureAsExpected(t *testing.T, got, expected *ipc.ServiceSignature) {
	if !reflect.DeepEqual(got.TypeDefs, expected.TypeDefs) {
		t.Errorf(`TypeDefs do not match: result "%v", want "%v"`, got.TypeDefs, expected.TypeDefs)
		return
	}
	if n, m := len(got.Methods), len(expected.Methods); n != m {
		t.Errorf(`Wrong number of signature methods: result "%d", want "%d"`, n, m)
		return
	}
	for gotName, gotMethod := range got.Methods {
		expectedMethod, ok := expected.Methods[gotName]
		if !ok {
			t.Errorf(`Method "%v" was expected but not found`, gotName)
			return
		}

		assertMethodSignatureAsExpected(t, gotMethod, expectedMethod)
	}
}

func TestFetching(t *testing.T) {
	sm := NewSignatureManager()
	got, err := sm.Signature(rt.R().NewContext(), name, client())
	if err != nil {
		t.Errorf(`Did not expect an error but got %v`, err)
		return
	}
	expected := expectedSignature()
	assertSignatureAsExpected(t, got, &expected)
}

func TestThatCachedAfterFetching(t *testing.T) {
	sm := NewSignatureManager().(*signatureManager)
	sig, _ := sm.Signature(rt.R().NewContext(), name, client())
	cache, ok := sm.cache[name]
	if !ok {
		t.Errorf(`Signature manager did not cache the results`)
		return
	}
	assertSignatureAsExpected(t, &cache.signature, sig)
}

func TestThatCacheIsUsed(t *testing.T) {
	client := client()
	sm := NewSignatureManager()

	// call twice
	sm.Signature(rt.R().NewContext(), name, client)
	sm.Signature(rt.R().NewContext(), name, client)

	// expect number of calls to Signature method of client to still be 1 since cache
	// should have been used despite the second call
	if client.TimesCalled("Signature") != 1 {
		t.Errorf("Signature cache was not used for the second call")
	}
}

func TestThatLastAccessedGetUpdated(t *testing.T) {
	client := client()
	sm := NewSignatureManager().(*signatureManager)
	sm.Signature(rt.R().NewContext(), name, client)
	// make last accessed be in the past to account for the fact that
	// two consecutive calls to time.Now() can return identical values.
	sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-ttl / 2)
	prevAccess := sm.cache[name].lastAccessed

	// access again
	sm.Signature(rt.R().NewContext(), name, client)
	newAccess := sm.cache[name].lastAccessed

	if !newAccess.After(prevAccess) {
		t.Errorf("LastAccessed was not updated for cache entry")
	}
}

func TestThatTTLExpires(t *testing.T) {
	client := client()
	sm := NewSignatureManager().(*signatureManager)
	sm.Signature(rt.R().NewContext(), name, client)

	// make last accessed go over the ttl
	sm.cache[name].lastAccessed = sm.cache[name].lastAccessed.Add(-2 * ttl)

	// make a second call
	sm.Signature(rt.R().NewContext(), name, client)

	// expect number of calls to Signature method of client to be 2 since cache should have expired
	if client.TimesCalled("Signature") != 2 {
		t.Errorf("Cache was still used but TTL had passed. It should have been fetched again")
	}
}
