// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// 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/x/lib/vlog"
	"v.io/x/ref/profiles/internal/testing/concurrency"
	"v.io/x/ref/profiles/internal/testing/concurrency/sync"
)

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)
	}
}
