// concurrency_test is a simple test of the framework for systematic
// testing of concurrency.
package concurrency_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"
	"time"

	"v.io/core/veyron/runtimes/google/testing/concurrency"
	"v.io/core/veyron/runtimes/google/testing/concurrency/sync"
	"v.io/core/veyron2/vlog"
)

var rw sync.RWMutex

// createRWMutexSets returns sets of thread identifiers that match the
// logic of rwMutexThreadClosure.
func createRWMutexSets(n int) (map[int]bool, map[int]bool, map[int]bool, map[int]bool, map[int]bool) {
	locks := make(map[int]bool)
	rlocks := make(map[int]bool)
	runlocks := make(map[int]bool)
	llocks := make(map[int]bool)
	lunlocks := make(map[int]bool)
	for i := 1; i <= n; i++ {
		switch i % 3 {
		case 0:
			locks[i] = true
		case 1:
			rlocks[i] = true
			runlocks[i] = true
		case 2:
			llocks[i] = true
			lunlocks[i] = true
		}
	}
	return locks, rlocks, runlocks, llocks, lunlocks
}

// generateRWMutexOutputs generates all legal outputs of sequencing calls to
// rw.Lock(), rw.Unlock(), rw.RLock(), rw.RUnlock(),
// rw.RLocker().Lock(), and rw.RLocker().Unlock(). The inputs identify
// the threads that wish to invoke these functions.
func generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks map[int]bool) []string {
	if length(locks) == 0 && length(rlocks) == 0 && length(runlocks) == 0 && length(llocks) == 0 && length(lunlocks) == 0 {
		// Base case.
		return []string{""}
	}
	result := make([]string, 0)
	if length(rlocks) == length(runlocks) && length(llocks) == length(lunlocks) {
		// rw.Lock() + rw.Unlock() can happen next if the previous calls
		// to rw.RLock(), rw.RUnlock, rw.RLocker().Lock(), and
		// rw.RLocker.Unlock() are balanced.
		for lock, ok := range locks {
			if ok {
				locks[lock] = false
				for _, s := range generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks) {
					result = append(result, fmt.Sprintf("%d:Lock()%d:Unlock()%s", lock, lock, s))
				}
				locks[lock] = true
			}
		}
	}
	for rlock, ok := range rlocks {
		if ok {
			// rw.RLock() can happen next any time.
			rlocks[rlock] = false
			for _, s := range generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks) {
				result = append(result, fmt.Sprintf("%d:RLock()%s", rlock, s))
			}
			rlocks[rlock] = true
		}
	}
	for runlock, ok := range runlocks {
		if ok {
			if ok := rlocks[runlock]; !ok {
				// rw.RUnlock() can happen next as long as the same thread
				// already invoked rw.RLock().
				runlocks[runlock] = false
				for _, s := range generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks) {
					result = append(result, fmt.Sprintf("%d:RUnlock()%s", runlock, s))
				}
				runlocks[runlock] = true
			}
		}
	}
	for llock, ok := range llocks {
		if ok {
			// rw.RLocker().Lock() can happen next any time.
			llocks[llock] = false
			for _, s := range generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks) {
				result = append(result, fmt.Sprintf("%d:RLocker().Lock()%s", llock, s))
			}
			llocks[llock] = true
		}
	}
	for lunlock, ok := range lunlocks {
		if ok {
			if ok := llocks[lunlock]; !ok {
				// rw.RLocker().Unlock() can happen next as long as the same thread
				// already invoked rw.RLocker().Lock().
				lunlocks[lunlock] = false
				for _, s := range generateRWMutexOutputs(locks, rlocks, runlocks, llocks, lunlocks) {
					result = append(result, fmt.Sprintf("%d:RLocker().Unlock()%s", lunlock, s))
				}
				lunlocks[lunlock] = true
			}
		}
	}
	return result
}

// rwMutexThreadClosure folds the input arguments inside of the
// function body as the testing framework only supports functions with
// no arguments.
func rwMutexThreadClosure(t *testing.T, n, max int, out *os.File) func() {
	return func() {
		defer concurrency.Exit()
		if n < max {
			child := rwMutexThreadClosure(t, n+1, max, out)
			concurrency.Start(child)
		}
		switch n % 3 {
		case 0:
			rw.Lock()
			fmt.Fprintf(out, "%d:Lock()", n)
		case 1:
			rw.RLock()
			fmt.Fprintf(out, "%d:RLock()", n)
		case 2:
			rw.RLocker().Lock()
			fmt.Fprintf(out, "%d:RLocker().Lock()", n)
		}
		switch n % 3 {
		case 0:
			rw.Unlock()
			fmt.Fprintf(out, "%d:Unlock()", n)
		case 1:
			rw.RUnlock()
			fmt.Fprintf(out, "%d:RUnlock()", n)
		case 2:
			rw.RLocker().Unlock()
			fmt.Fprintf(out, "%d:RLocker().Unlock()", n)
		}
	}
}

// TestRWMutex runs rwMutexThreadClosure() without systematically
// testing concurrency.
func TestRWMutex(t *testing.T) {
	for n := 2; n < 5; n++ {
		thread := rwMutexThreadClosure(t, 1, n, nil)
		thread()
	}
}

// TestRWMutexExplore runs rwMutexThreadClosure() using the framework
// for systematic testing of concurrency, checking that the
// exploration explores the correct number of interleavings.
func TestRWMutexExplore(t *testing.T) {
	for n := 2; n < 5; n++ {
		out, err := ioutil.TempFile("", "")
		if err != nil {
			t.Fatalf("TempFile() failed: %v", err)
		}
		defer os.Remove(out.Name())
		defer out.Close()
		body := rwMutexThreadClosure(t, 1, n, out)
		tester := concurrency.Init(setup, body, cleanupClosure(out))
		defer concurrency.Finish()
		niterations, err := tester.Explore()
		if err != nil {
			t.Fatalf("Unexpected error encountered: %v", err)
		}
		outputs := processOutput(t, out)
		expectedOutputs := generateRWMutexOutputs(createRWMutexSets(n))
		checkExpectedOutputs(t, outputs, expectedOutputs)
		checkUnexpectedOutputs(t, outputs, expectedOutputs)
		vlog.VI(1).Infof("Explored %v iterations.", niterations)
	}
}

// TestRWMutexExploreN runs rwMutexThreadClosure() using the framework
// for systematic testing of concurrency, checking that the
// exploration explores at most the given number of interleavings.
func TestRWMutexExploreN(t *testing.T) {
	stopAfter := 100
	for n := 2; n < 5; n++ {
		out, err := ioutil.TempFile("", "")
		if err != nil {
			t.Fatalf("TempFile() failed: %v", err)
		}
		defer os.Remove(out.Name())
		defer out.Close()
		body := rwMutexThreadClosure(t, 1, n, out)
		tester := concurrency.Init(setup, body, cleanupClosure(out))
		defer concurrency.Finish()
		niterations, err := tester.ExploreN(stopAfter)
		if err != nil {
			t.Fatalf("Unexpected error encountered: %v", err)
		}
		outputs := processOutput(t, out)
		expectedOutputs := generateRWMutexOutputs(createRWMutexSets(n))
		checkUnexpectedOutputs(t, outputs, expectedOutputs)
		if niterations < stopAfter {
			checkExpectedOutputs(t, outputs, expectedOutputs)
		}
		if niterations > stopAfter {
			t.Fatalf("Unexpected number of iterations: expected at most %v, got %v", stopAfter, niterations)
		}
		vlog.VI(1).Infof("Explored %v iterations.", niterations)
	}
}

// TestRWMutexExploreFor runs rwMutexThreadClosure() using the
// framework for systematic testing of concurrency, checking that the
// exploration respects the given "soft" deadline.
func TestRWMutexExploreFor(t *testing.T) {
	deadline := 10 * time.Millisecond
	for n := 2; n < 5; n++ {
		out, err := ioutil.TempFile("", "")
		if err != nil {
			t.Fatalf("TempFile() failed: %v", err)
		}
		defer os.Remove(out.Name())
		defer out.Close()
		body := rwMutexThreadClosure(t, 1, n, out)
		tester := concurrency.Init(setup, body, cleanupClosure(out))
		defer concurrency.Finish()
		start := time.Now()
		niterations, err := tester.ExploreFor(deadline)
		if err != nil {
			t.Fatalf("Unexpected error encountered: %v", err)
		}
		end := time.Now()
		outputs := processOutput(t, out)
		expectedOutputs := generateRWMutexOutputs(createRWMutexSets(n))
		checkUnexpectedOutputs(t, outputs, expectedOutputs)
		if start.Add(deadline).After(end) {
			checkExpectedOutputs(t, outputs, expectedOutputs)
		}
		vlog.VI(1).Infof("Explored %v iterations.", niterations)
	}
}
