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

package gocheck_test

import (
	"flag"
	"fmt"
	"launchpad.net/gocheck"
	"os"
	"regexp"
	"runtime"
	"testing"
	"time"
)

// 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) {
	gocheck.TestingT(t)
	if suitesRun != suitesRunExpected && flag.Lookup("gocheck.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 *gocheck.C, obtained, expected interface{}) (result bool, line int) {
	return c.Check(obtained, gocheck.Equals, expected), getMyLine()
}

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

type FailHelper struct {
	testLine int
}

func (s *FailHelper) TestLogAndFail(c *gocheck.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 *gocheck.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 *gocheck.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 *gocheck.C) {
	s.trace("SetUpSuite", c)
}

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

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

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

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

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

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

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

// -----------------------------------------------------------------------
// 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 *gocheck.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",
			expected.name)
	} 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)
		}
	}
}
