// Copyright 2014 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package memcache

import (
	"fmt"
	"testing"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/memcache"
)

var errRPC = fmt.Errorf("RPC error")

func TestGetRequest(t *testing.T) {
	serviceCalled := false
	apiKey := "lyric"

	c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
		// Test request.
		if n := len(req.Key); n != 1 {
			t.Errorf("got %d want 1", n)
			return nil
		}
		if k := string(req.Key[0]); k != apiKey {
			t.Errorf("got %q want %q", k, apiKey)
		}

		serviceCalled = true
		return nil
	})

	// Test the "forward" path from the API call parameters to the
	// protobuf request object. (The "backward" path from the
	// protobuf response object to the API call response,
	// including the error response, are handled in the next few
	// tests).
	Get(c, apiKey)
	if !serviceCalled {
		t.Error("Service was not called as expected")
	}
}

func TestGetResponseHit(t *testing.T) {
	key := "lyric"
	value := "Where the buffalo roam"

	c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
		res.Item = []*pb.MemcacheGetResponse_Item{
			{Key: []byte(key), Value: []byte(value)},
		}
		return nil
	})
	apiItem, err := Get(c, key)
	if apiItem == nil || apiItem.Key != key || string(apiItem.Value) != value {
		t.Errorf("got %q, %q want {%q,%q}, nil", apiItem, err, key, value)
	}
}

func TestGetResponseMiss(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
		// don't fill in any of the response
		return nil
	})
	_, err := Get(c, "something")
	if err != ErrCacheMiss {
		t.Errorf("got %v want ErrCacheMiss", err)
	}
}

func TestGetResponseRPCError(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
		return errRPC
	})

	if _, err := Get(c, "something"); err != errRPC {
		t.Errorf("got %v want errRPC", err)
	}
}

func TestAddRequest(t *testing.T) {
	var apiItem = &Item{
		Key:   "lyric",
		Value: []byte("Oh, give me a home"),
	}

	serviceCalled := false

	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
		// Test request.
		pbItem := req.Item[0]
		if k := string(pbItem.Key); k != apiItem.Key {
			t.Errorf("got %q want %q", k, apiItem.Key)
		}
		if v := string(apiItem.Value); v != string(pbItem.Value) {
			t.Errorf("got %q want %q", v, string(pbItem.Value))
		}
		if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_ADD {
			t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_ADD)
		}

		serviceCalled = true
		return nil
	})

	Add(c, apiItem)
	if !serviceCalled {
		t.Error("Service was not called as expected")
	}
}

func TestAddResponseStored(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
		return nil
	})

	if err := Add(c, &Item{}); err != nil {
		t.Errorf("got %v want nil", err)
	}
}

func TestAddResponseNotStored(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_NOT_STORED}
		return nil
	})

	if err := Add(c, &Item{}); err != ErrNotStored {
		t.Errorf("got %v want ErrNotStored", err)
	}
}

func TestAddResponseError(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
		return nil
	})

	if err := Add(c, &Item{}); err != ErrServerError {
		t.Errorf("got %v want ErrServerError", err)
	}
}

func TestAddResponseRPCError(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		return errRPC
	})

	if err := Add(c, &Item{}); err != errRPC {
		t.Errorf("got %v want errRPC", err)
	}
}

func TestSetRequest(t *testing.T) {
	var apiItem = &Item{
		Key:   "lyric",
		Value: []byte("Where the buffalo roam"),
	}

	serviceCalled := false

	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
		// Test request.
		if n := len(req.Item); n != 1 {
			t.Errorf("got %d want 1", n)
			return nil
		}
		pbItem := req.Item[0]
		if k := string(pbItem.Key); k != apiItem.Key {
			t.Errorf("got %q want %q", k, apiItem.Key)
		}
		if v := string(pbItem.Value); v != string(apiItem.Value) {
			t.Errorf("got %q want %q", v, string(apiItem.Value))
		}
		if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_SET {
			t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_SET)
		}

		serviceCalled = true
		return nil
	})

	Set(c, apiItem)
	if !serviceCalled {
		t.Error("Service was not called as expected")
	}
}

func TestSetResponse(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
		return nil
	})

	if err := Set(c, &Item{}); err != nil {
		t.Errorf("got %v want nil", err)
	}
}

func TestSetResponseError(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
		res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
		return nil
	})

	if err := Set(c, &Item{}); err != ErrServerError {
		t.Errorf("got %v want ErrServerError", err)
	}
}

func TestNamespaceResetting(t *testing.T) {
	namec := make(chan *string, 1)
	c0 := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
		namec <- req.NameSpace
		return errRPC
	})

	// Check that wrapping c0 in a namespace twice works correctly.
	c1, err := appengine.Namespace(c0, "A")
	if err != nil {
		t.Fatalf("appengine.Namespace: %v", err)
	}
	c2, err := appengine.Namespace(c1, "") // should act as the original context
	if err != nil {
		t.Fatalf("appengine.Namespace: %v", err)
	}

	Get(c0, "key")
	if ns := <-namec; ns != nil {
		t.Errorf(`Get with c0: ns = %q, want nil`, *ns)
	}

	Get(c1, "key")
	if ns := <-namec; ns == nil {
		t.Error(`Get with c1: ns = nil, want "A"`)
	} else if *ns != "A" {
		t.Errorf(`Get with c1: ns = %q, want "A"`, *ns)
	}

	Get(c2, "key")
	if ns := <-namec; ns != nil {
		t.Errorf(`Get with c2: ns = %q, want nil`, *ns)
	}
}

func TestGetMultiEmpty(t *testing.T) {
	serviceCalled := false
	c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
		serviceCalled = true
		return nil
	})

	// Test that the Memcache service is not called when
	// GetMulti is passed an empty slice of keys.
	GetMulti(c, []string{})
	if serviceCalled {
		t.Error("Service was called but should not have been")
	}
}
