// This file contains just a few generic helpers which are used by the
// other test files.

package check_test

import (
	"flag"
	"fmt"
	"os"
	"regexp"
	"runtime"
	"testing"
	"time"

	"gopkg.in/check.v1"
)

// We count the number of suites run at least to get a vague hint that the
// test suite is behaving as it should.  Otherwise a bug introduced at the
// very core of the system could go unperceived.
const suitesRunExpected = 8

var suitesRun int = 0

func Test(t *testing.T) {
	check.TestingT(t)
	if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" {
		critical(fmt.Sprintf("Expected %d suites to run rather than %d",
			suitesRunExpected, suitesRun))
	}
}

// -----------------------------------------------------------------------
// Helper functions.

// Break down badly.  This is used in test cases which can't yet assume
// that the fundamental bits are working.
func critical(error string) {
	fmt.Fprintln(os.Stderr, "CRITICAL: "+error)
	os.Exit(1)
}

// Return the file line where it's called.
func getMyLine() int {
	if _, _, line, ok := runtime.Caller(1); ok {
		return line
	}
	return -1
}

// -----------------------------------------------------------------------
// Helper type implementing a basic io.Writer for testing output.

// Type implementing the io.Writer interface for analyzing output.
type String struct {
	value string
}

// The only function required by the io.Writer interface.  Will append
// written data to the String.value string.
func (s *String) Write(p []byte) (n int, err error) {
	s.value += string(p)
	return len(p), nil
}

// Trivial wrapper to test errors happening on a different file
// than the test itself.
func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) {
	return c.Check(obtained, check.Equals, expected), getMyLine()
}

// -----------------------------------------------------------------------
// Helper suite for testing basic fail behavior.

type FailHelper struct {
	testLine int
}

func (s *FailHelper) TestLogAndFail(c *check.C) {
	s.testLine = getMyLine() - 1
	c.Log("Expected failure!")
	c.Fail()
}

// -----------------------------------------------------------------------
// Helper suite for testing basic success behavior.

type SuccessHelper struct{}

func (s *SuccessHelper) TestLogAndSucceed(c *check.C) {
	c.Log("Expected success!")
}

// -----------------------------------------------------------------------
// Helper suite for testing ordering and behavior of fixture.

type FixtureHelper struct {
	calls   []string
	panicOn string
	skip    bool
	skipOnN int
	sleepOn string
	sleep   time.Duration
	bytes   int64
}

func (s *FixtureHelper) trace(name string, c *check.C) {
	s.calls = append(s.calls, name)
	if name == s.panicOn {
		panic(name)
	}
	if s.sleep > 0 && s.sleepOn == name {
		time.Sleep(s.sleep)
	}
	if s.skip && s.skipOnN == len(s.calls)-1 {
		c.Skip("skipOnN == n")
	}
}

func (s *FixtureHelper) SetUpSuite(c *check.C) {
	s.trace("SetUpSuite", c)
}

func (s *FixtureHelper) TearDownSuite(c *check.C) {
	s.trace("TearDownSuite", c)
}

func (s *FixtureHelper) SetUpTest(c *check.C) {
	s.trace("SetUpTest", c)
}

func (s *FixtureHelper) TearDownTest(c *check.C) {
	s.trace("TearDownTest", c)
}

func (s *FixtureHelper) Test1(c *check.C) {
	s.trace("Test1", c)
}

func (s *FixtureHelper) Test2(c *check.C) {
	s.trace("Test2", c)
}

func (s *FixtureHelper) Benchmark1(c *check.C) {
	s.trace("Benchmark1", c)
	for i := 0; i < c.N; i++ {
		time.Sleep(s.sleep)
	}
}

func (s *FixtureHelper) Benchmark2(c *check.C) {
	s.trace("Benchmark2", c)
	c.SetBytes(1024)
	for i := 0; i < c.N; i++ {
		time.Sleep(s.sleep)
	}
}

func (s *FixtureHelper) Benchmark3(c *check.C) {
	var x []int64
	s.trace("Benchmark3", c)
	for i := 0; i < c.N; i++ {
		time.Sleep(s.sleep)
		x = make([]int64, 5)
		_ = x
	}
}

// -----------------------------------------------------------------------
// Helper which checks the state of the test and ensures that it matches
// the given expectations.  Depends on c.Errorf() working, so shouldn't
// be used to test this one function.

type expectedState struct {
	name   string
	result interface{}
	failed bool
	log    string
}

// Verify the state of the test.  Note that since this also verifies if
// the test is supposed to be in a failed state, no other checks should
// be done in addition to what is being tested.
func checkState(c *check.C, result interface{}, expected *expectedState) {
	failed := c.Failed()
	c.Succeed()
	log := c.GetTestLog()
	matched, matchError := regexp.MatchString("^"+expected.log+"$", log)
	if matchError != nil {
		c.Errorf("Error in matching expression used in testing %s: %v",
			expected.name, matchError)
	} else if !matched {
		c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------",
			expected.name, log, expected.log)
	}
	if result != expected.result {
		c.Errorf("%s returned %#v rather than %#v",
			expected.name, result, expected.result)
	}
	if failed != expected.failed {
		if failed {
			c.Errorf("%s has failed when it shouldn't", expected.name)
		} else {
			c.Errorf("%s has not failed when it should", expected.name)
		}
	}
}
