package lib

import (
	"errors"
	"reflect"
	"testing"
	"time"

	"veyron2/context"
	"veyron2/ipc"
	"veyron2/naming"
	"veyron2/rt"
	"veyron2/vdl/vdlutil"
	"veyron2/verror"

	hps "veyron/examples/wspr_sample"
)

// getCacheClient initializes the runtime and creates a client binding.
func getCacheClient(address string) (hps.Cache, error) {
	rt.Init()

	// Bind to a rooted, terminal name to bypass the MountTable which isn't
	// actually used, nor needed, in these tests.
	s, err := hps.BindCache(naming.JoinAddressName(address, "//cache"))
	if err != nil {
		return nil, err
	}

	return s, nil
}

// TestValueSetGet tests setting values and then calling various Get* functions.
func TestValueSetGet(t *testing.T) {
	type testCase struct {
		mapFieldName    string
		nameOfGetMethod string
		v               interface{}
		shouldGetError  bool
	}
	tests := []testCase{
		testCase{"val", "Get", "Test", false},
		testCase{"val", "Get", 4, false},
		testCase{"val", "Get", struct {
			X int
			Y string
		}{4, "Test"}, false},
		testCase{"i32", "GetAsInt32", int32(1), false},
		testCase{"i64", "GetAsInt64", int64(1), false},
		testCase{"byt", "GetAsByte", byte(1), false},
		testCase{"ui32", "GetAsUint32", uint32(1), false},
		testCase{"ui64", "GetAsUint64", uint64(1), false},
		testCase{"fl32", "GetAsFloat32", float32(1), false},
		testCase{"fl64", "GetAsFloat64", float64(1), false},
		testCase{"b", "GetAsBool", true, false},
		testCase{"s", "GetAsString", "Test", false},
		testCase{"err", "GetAsError", verror.ToStandard(errors.New("Test Error")), false},
		testCase{"err_i8", "GetAsByte", int64(4), true},
		testCase{"err_i64", "GetAsInt64", int8(1), true},
		testCase{"err_string", "GetAsString", true, true},
	}
	r := rt.Init()
	ctx := r.NewContext()

	s, endpoint, err := StartServer(r)
	if err != nil {
		t.Fatal("failed to start server: ", err)
	}
	defer s.Stop()
	c, err := getCacheClient(endpoint.String())
	if err != nil {
		t.Fatal("failed to connect client: ", err)
	}
	for _, test := range tests {
		// Call Set().
		if err := c.Set(ctx, test.mapFieldName, test.v); err != nil {
			t.Errorf("error setting: %v (test case: %v)", err, test)
			continue
		}

		meth := reflect.ValueOf(c).MethodByName(test.nameOfGetMethod)
		out := meth.Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(test.mapFieldName)})
		if !test.shouldGetError {
			if out[1].Interface() != nil {
				t.Errorf("error getting: %v (test case: %v)", err, test)
				continue
			}
			if out[0].Interface() != test.v {
				t.Errorf("returned result does not match")
			}
		} else if out[1].Interface() == nil {
			t.Errorf("expected error in case %v", test)
		}

	}
}

// settable mirrors the cache's Set method to provide a consistent way to populate test cases.
type settable interface {
	Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error
}

// populateObject populates a settable with 12 values.
func populateObject(ctx context.T, s settable) error {
	if err := s.Set(ctx, "A", int8(3)); err != nil {
		return err
	}
	// Set "A" again to ensure it takes the second value.
	if err := s.Set(ctx, "A", "A"); err != nil {
		return err
	}
	if err := s.Set(ctx, "B", uint16(5)); err != nil {
		return err
	}
	if err := s.Set(ctx, "C", uint32(7)); err != nil {
		return err
	}
	if err := s.Set(ctx, "D", verror.ToStandard(errors.New("Err"))); err != nil {
		return err
	}
	if err := s.Set(ctx, "E", true); err != nil {
		return err
	}
	if err := s.Set(ctx, "F", float32(5.4)); err != nil {
		return err
	}
	if err := s.Set(ctx, "G", struct {
		X int
		Y string
	}{4, "G"}); err != nil {
		return err
	}
	if err := s.Set(ctx, "H", uint64(8)); err != nil {
		return err
	}
	if err := s.Set(ctx, "I", "I"); err != nil {
		return err
	}
	if err := s.Set(ctx, "J", float64(8.3)); err != nil {
		return err
	}
	if err := s.Set(ctx, "K", int64(2)); err != nil {
		return err
	}
	if err := s.Set(ctx, "L", int8(9)); err != nil {
		return err
	}
	return nil
}

// setupManyResults starts a server and client and populates the server with the values in populateObject.
func setupManyResults(t *testing.T) (hps.Cache, ipc.Server) {
	r := rt.Init()
	s, endpoint, err := StartServer(r)
	if err != nil {
		t.Fatal("failed to start server: ", err)
	}
	c, err := getCacheClient(endpoint.String())
	if err != nil {
		t.Fatal("failed to connect client: ", err)
	}

	if err := populateObject(r.NewContext(), c.(settable)); err != nil {
		t.Fatal("error populating cache: ", err)
	}

	return c, s
}

// settableMap is a map that implements the settable interface.
type settableMap map[string]vdlutil.Any

func (sm settableMap) Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error {
	sm[key] = val
	return nil
}

// TestAsMap tests that AsMap returns the correct results.
func TestAsMap(t *testing.T) {
	c, s := setupManyResults(t)
	defer s.Stop()

	ctx := rt.R().NewContext()

	res, err := c.AsMap(ctx)
	if err != nil {
		t.Fatal("error calling AsMap: ", err)
	}

	m := settableMap(make(map[string]vdlutil.Any))
	if err := populateObject(ctx, m); err != nil {
		t.Fatal("error populating map: ", err)
	}

	for key, val := range m {
		otherVal := res[key]
		if val != otherVal {
			t.Errorf("didn't match: %v and %v", val, otherVal)
		}
	}
}

// TestKeyValuePairs tests that KeyValuePairs returns the correct results.
func TestKeyValuePairs(t *testing.T) {
	c, s := setupManyResults(t)
	defer s.Stop()

	ctx := rt.R().NewContext()
	res, err := c.KeyValuePairs(ctx)
	if err != nil {
		t.Fatal("error calling KeyValuePairs: ", err)
	}

	m := settableMap(make(map[string]vdlutil.Any))
	if err := populateObject(ctx, m); err != nil {
		t.Fatal("error populating map: ", err)
	}

	for _, kvp := range res {
		otherVal := m[kvp.Key]
		if kvp.Value != otherVal {
			t.Errorf("didn't match: %v and %v", kvp.Value, otherVal)
		}
	}
}

// TestKeyPageAndSize tests the KeyPage and size methods.
func TestKeyPageAndSize(t *testing.T) {
	c, s := setupManyResults(t)
	defer s.Stop()

	ctx := rt.R().NewContext()
	sz, err := c.Size(ctx)
	if err != nil {
		t.Fatal("error calling Size: ", err)
	}
	if sz != 12 {
		t.Fatal("wrong number of results: ", sz)
	}

	res, err := c.KeyPage(ctx, 1)
	if err != nil {
		t.Fatal("error calling AsMap: ", err)
	}

	if res[0] != "K" || res[1] != "L" || res[2] != "" {
		t.Fatalf("incorrect page results: %v", res)
	}
}

// TestMostRecentSet tests the MostRecentSet method.
func TestMostRecentSet(t *testing.T) {
	c, s := setupManyResults(t)
	defer s.Stop()

	ctx := rt.R().NewContext()

	timeBefore := time.Now().Unix()
	if err := c.Set(ctx, "B", int32(8)); err != nil {
		t.Fatal("error calling Set: ", err)
	}
	timeAfter := time.Now().Unix()

	kvp, setTime, err := c.MostRecentSet(ctx)
	if err != nil {
		t.Fatal("error calling MostRecentSet: ", err)
	}

	if kvp.Key != "B" || kvp.Value != int32(8) {
		t.Errorf("unexpected key value pair: %v", kvp)
	}

	if setTime < timeBefore || setTime > timeAfter {
		t.Errorf("time %v out of range [%v, %v]", setTime, timeBefore, timeAfter)
	}
}

// TestMultiGet tests the MultiGet method.
func TestMultiGet(t *testing.T) {
	c, s := setupManyResults(t)
	defer s.Stop()

	stream, err := c.MultiGet(rt.R().NewContext())
	if err != nil {
		t.Fatal("error calling MultiGet: ", err)
	}
	stream.Send("A")
	stream.Send("C")
	stream.Send("E")

	if stream.Advance() {
		if stream.Value() != "A" {
			t.Errorf("value for 'A' didn't match")
		}
	} else {
		t.Fatal("error on advance: %v", stream.Err())
	}

	if stream.Advance() {
		if stream.Value() != uint32(7) {
			t.Errorf("value for 'C' didn't match")
		}
	} else {
		t.Fatal("error on advance: %v", stream.Err())
	}

	if stream.Advance() {
		if stream.Value() != true {
			t.Errorf("value for 'E' didn't match")
		}
	} else {
		t.Fatal("error on advance: %v", stream.Err())
	}

	stream.CloseSend()
}
