package xproto

/*
	Tests for XGB.

	These tests only test the core X protocol at the moment. It isn't even
	close to complete coverage (and probably never will be), but it does test
	a number of different corners: requests with no replies, requests without
	replies, checked (i.e., synchronous) errors, unchecked (i.e., asynchronous)
	errors, and sequence number wrapping.

	There are also a couple of benchmarks that show the difference between
	correctly issuing lots of requests and gathering replies and
	incorrectly doing the same. (This particular difference is one of the
	claimed advantages of the XCB, and therefore XGB, family.)

	In sum, these tests are more focused on testing the core xgb package itself,
	rather than whether xproto has properly implemented the core X client
	protocol.
*/

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"testing"
	"time"

	"github.com/BurntSushi/xgb"
)

// The X connection used throughout testing.
var X *xgb.Conn

func TestMain(m *testing.M) {
	if os.Getenv("DISPLAY") == "" {
		log.Printf("No X; Skipping tests")
		os.Exit(0)
	}

	var err error
	X, err = xgb.NewConn()
	if err != nil {
		log.Fatal(err)
	}
	rand.Seed(time.Now().UnixNano())
	go grabEvents()

	os.Exit(m.Run())
}

/******************************************************************************/
// Tests
/******************************************************************************/

// TestSynchronousError purposefully causes a BadWindow error in a
// MapWindow request, and checks it synchronously.
func TestSynchronousError(t *testing.T) {
	err := MapWindowChecked(X, 0).Check() // resource 0 is always invalid
	if err == nil {
		t.Fatalf("MapWindow: A MapWindow request that should return an " +
			"error has returned a nil error.")
	}
	verifyMapWindowError(t, err)
}

// TestAsynchronousError does the same thing as TestSynchronousError, but
// grabs the error asynchronously instead.
func TestAsynchronousError(t *testing.T) {
	MapWindow(X, 0) // resource id 0 is always invalid

	evOrErr := waitForEvent(t, 5)
	if evOrErr.ev != nil {
		t.Fatalf("After issuing an erroneous MapWindow request, we have "+
			"received an event rather than an error: %s", evOrErr.ev)
	}
	verifyMapWindowError(t, evOrErr.err)
}

// TestCookieBuffer issues (2^16) + n requets *without* replies to guarantee
// that the sequence number wraps and that the cookie buffer will have to
// flush itself (since there are no replies coming in to flush it).
// And just like TestSequenceWrap, we issue another request with a reply
// at the end to make sure XGB is still working properly.
func TestCookieBuffer(t *testing.T) {
	n := (1 << 16) + 10
	for i := 0; i < n; i++ {
		NoOperation(X)
	}
	TestProperty(t)
}

// TestSequenceWrap issues (2^16) + n requests w/ replies to guarantee that the
// sequence number (which is a 16 bit integer) will wrap. It then issues one
// final request to ensure things still work properly.
func TestSequenceWrap(t *testing.T) {
	n := (1 << 16) + 10
	for i := 0; i < n; i++ {
		_, err := InternAtom(X, false, 5, "RANDO").Reply()
		if err != nil {
			t.Fatalf("InternAtom: %s", err)
		}
	}
	TestProperty(t)
}

// TestProperty tests whether a random value can be set and read.
func TestProperty(t *testing.T) {
	propName := randString(20) // whatevs
	writeVal := randString(20)
	readVal, err := changeAndGetProp(propName, writeVal)
	if err != nil {
		t.Error(err)
	}

	if readVal != writeVal {
		t.Errorf("The value written, '%s', is not the same as the "+
			"value read '%s'.", writeVal, readVal)
	}
}

// TestWindowEvents creates a window, maps it, listens for configure notify
// events, issues a configure request, and checks for the appropriate
// configure notify event.
// This probably violates the notion of "test one thing and test it well,"
// but testing X stuff is unique since it involves so much state.
// Each request is checked to make sure there are no errors returned. If there
// is an error, the test is failed.
// You may see a window appear quickly and then disappear. Do not be alarmed :P
// It's possible that this test will yield a false negative because we cannot
// control our environment. That is, the window manager could override the
// placement set. However, we set override redirect on the window, so the
// window manager *shouldn't* touch our window if it is well-behaved.
func TestWindowEvents(t *testing.T) {
	// The geometry to set the window.
	gx, gy, gw, gh := 200, 400, 1000, 300

	wid, err := NewWindowId(X)
	if err != nil {
		t.Fatalf("NewId: %s", err)
	}

	screen := Setup(X).DefaultScreen(X) // alias
	err = CreateWindowChecked(X, screen.RootDepth, wid, screen.Root,
		0, 0, 500, 500, 0,
		WindowClassInputOutput, screen.RootVisual,
		CwBackPixel|CwOverrideRedirect, []uint32{0xffffffff, 1}).Check()
	if err != nil {
		t.Fatalf("CreateWindow: %s", err)
	}

	err = MapWindowChecked(X, wid).Check()
	if err != nil {
		t.Fatalf("MapWindow: %s", err)
	}

	// We don't listen in the CreateWindow request so that we don't get
	// a MapNotify event.
	err = ChangeWindowAttributesChecked(X, wid,
		CwEventMask, []uint32{EventMaskStructureNotify}).Check()
	if err != nil {
		t.Fatalf("ChangeWindowAttributes: %s", err)
	}

	err = ConfigureWindowChecked(X, wid,
		ConfigWindowX|ConfigWindowY|
			ConfigWindowWidth|ConfigWindowHeight,
		[]uint32{uint32(gx), uint32(gy), uint32(gw), uint32(gh)}).Check()
	if err != nil {
		t.Fatalf("ConfigureWindow: %s", err)
	}

	evOrErr := waitForEvent(t, 5)
	switch event := evOrErr.ev.(type) {
	case ConfigureNotifyEvent:
		if event.X != int16(gx) {
			t.Fatalf("x was set to %d but ConfigureNotify reports %d",
				gx, event.X)
		}
		if event.Y != int16(gy) {
			t.Fatalf("y was set to %d but ConfigureNotify reports %d",
				gy, event.Y)
		}
		if event.Width != uint16(gw) {
			t.Fatalf("width was set to %d but ConfigureNotify reports %d",
				gw, event.Width)
		}
		if event.Height != uint16(gh) {
			t.Fatalf("height was set to %d but ConfigureNotify reports %d",
				gh, event.Height)
		}
	default:
		t.Fatalf("Expected a ConfigureNotifyEvent but got %T instead.", event)
	}

	// Okay, clean up!
	err = ChangeWindowAttributesChecked(X, wid,
		CwEventMask, []uint32{0}).Check()
	if err != nil {
		t.Fatalf("ChangeWindowAttributes: %s", err)
	}

	err = DestroyWindowChecked(X, wid).Check()
	if err != nil {
		t.Fatalf("DestroyWindow: %s", err)
	}
}

// Calls GetFontPath function, Issue #12
func TestGetFontPath(t *testing.T) {
	fontPathReply, err := GetFontPath(X).Reply()
	if err != nil {
		t.Fatalf("GetFontPath: %v", err)
	}
	_ = fontPathReply
}

func TestListFonts(t *testing.T) {
	listFontsReply, err := ListFonts(X, 10, 1, "*").Reply()
	if err != nil {
		t.Fatalf("ListFonts: %v", err)
	}
	_ = listFontsReply
}

/******************************************************************************/
// Benchmarks
/******************************************************************************/

// BenchmarkInternAtomsGood shows how many requests with replies
// *should* be sent and gathered from the server. Namely, send as many
// requests as you can at once, then go back and gather up all the replies.
// More importantly, this approach can exploit parallelism when
// GOMAXPROCS > 1.
// Run with `go test -run 'nomatch' -bench '.*' -cpu 1,2,6` if you have
// multiple cores to see the improvement that parallelism brings.
func BenchmarkInternAtomsGood(b *testing.B) {
	b.StopTimer()
	names := seqNames(b.N)

	b.StartTimer()
	cookies := make([]InternAtomCookie, b.N)
	for i := 0; i < b.N; i++ {
		cookies[i] = InternAtom(X, false, uint16(len(names[i])), names[i])
	}
	for _, cookie := range cookies {
		cookie.Reply()
	}
}

// BenchmarkInternAtomsBad shows how *not* to issue a lot of requests with
// replies. Namely, each subsequent request isn't issued *until* the last
// reply is made. This implies a round trip to the X server for every
// iteration.
func BenchmarkInternAtomsPoor(b *testing.B) {
	b.StopTimer()
	names := seqNames(b.N)

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		InternAtom(X, false, uint16(len(names[i])), names[i]).Reply()
	}
}

/******************************************************************************/
// Helper functions
/******************************************************************************/

// changeAndGetProp sets property 'prop' with value 'val'.
// It then gets the value of that property and returns it.
// (It's used to check that the 'val' going in is the same 'val' going out.)
// It tests both requests with and without replies (GetProperty and
// ChangeProperty respectively.)
func changeAndGetProp(prop, val string) (string, error) {
	setup := Setup(X)
	root := setup.DefaultScreen(X).Root

	propAtom, err := InternAtom(X, false, uint16(len(prop)), prop).Reply()
	if err != nil {
		return "", fmt.Errorf("InternAtom: %s", err)
	}

	typName := "UTF8_STRING"
	typAtom, err := InternAtom(X, false, uint16(len(typName)), typName).Reply()
	if err != nil {
		return "", fmt.Errorf("InternAtom: %s", err)
	}

	err = ChangePropertyChecked(X, PropModeReplace, root, propAtom.Atom,
		typAtom.Atom, 8, uint32(len(val)), []byte(val)).Check()
	if err != nil {
		return "", fmt.Errorf("ChangeProperty: %s", err)
	}

	reply, err := GetProperty(X, false, root, propAtom.Atom,
		GetPropertyTypeAny, 0, (1<<32)-1).Reply()
	if err != nil {
		return "", fmt.Errorf("GetProperty: %s", err)
	}
	if reply.Format != 8 {
		return "", fmt.Errorf("Property reply format is %d but it should be 8.",
			reply.Format)
	}

	return string(reply.Value), nil
}

// verifyMapWindowError takes an error that is returned with an invalid
// MapWindow request with a window Id of 0 and makes sure the error is the
// right type and contains the correct values.
func verifyMapWindowError(t *testing.T, err error) {
	switch e := err.(type) {
	case WindowError:
		if e.BadValue != 0 {
			t.Fatalf("WindowError should report a bad value of 0 but "+
				"it reports %d instead.", e.BadValue)
		}
		if e.MajorOpcode != 8 {
			t.Fatalf("WindowError should report a major opcode of 8 "+
				"(which is a MapWindow request), but it reports %d instead.",
				e.MajorOpcode)
		}
	default:
		t.Fatalf("Expected a WindowError but got %T instead.", e)
	}
}

// randString generates a random string of length n.
func randString(n int) string {
	byts := make([]byte, n)
	for i := 0; i < n; i++ {
		rando := rand.Intn(53)
		switch {
		case rando <= 25:
			byts[i] = byte(65 + rando)
		case rando <= 51:
			byts[i] = byte(97 + rando - 26)
		default:
			byts[i] = ' '
		}
	}
	return string(byts)
}

// seqNames creates a slice of NAME0, NAME1, ..., NAMEN.
func seqNames(n int) []string {
	names := make([]string, n)
	for i := range names {
		names[i] = fmt.Sprintf("NAME%d", i)
	}
	return names
}

// evErr represents a value that is either an event or an error.
type evErr struct {
	ev  xgb.Event
	err xgb.Error
}

// channel used to pass evErrs.
var evOrErrChan = make(chan evErr, 0)

// grabEvents is a goroutine that reads events off the wire.
// We used this instead of WaitForEvent directly in our tests so that
// we can timeout and fail a test.
func grabEvents() {
	for {
		ev, err := X.WaitForEvent()
		evOrErrChan <- evErr{ev, err}
	}
}

// waitForEvent asks the evOrErrChan channel for an event.
// If it doesn't get an event in 'n' seconds, the current test is failed.
func waitForEvent(t *testing.T, n int) evErr {
	var evOrErr evErr

	select {
	case evOrErr = <-evOrErrChan:
	case <-time.After(time.Second * 5):
		t.Fatalf("After waiting 5 seconds for an event or an error, " +
			"we have timed out.")
	}

	return evOrErr
}
