package util

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/onsi/ginkgo"
)

func Repeat(times int, f func()) func() {
	return func() {
		for i := 0; i < times; i++ {
			f()
		}
	}
}

// ParameterizedDescribe works as a ginkgo.Describe, the only difference is that it supports an extra flag.FlagSet
// that allows you to retrieve parameters from command line arguments.
//
// check out testcase/examples/dsl.go for examples.
func ParameterizedDescribe(name string, body func(flagSet *flag.FlagSet)) bool {
	if strings.Contains(name, " ") {
		panic("ERROR: name of ParameterizedDescribe should not contains whitespace.\nit's recommended (though not enforced) to use UpperCamelCase to name your ParameterizedDescribe, e.g. TikvOOM.")
	}

	return ginkgo.Describe(name, func() {
		flags := flag.NewFlagSet(name, flag.ExitOnError)
		body(flags)

		args := flag.Args()
		// TODO(cosven): The name should not be conflict with other command. add validation for name.
		if len(args) >= 1 {
			if args[0] == name {
				err := flags.Parse(args[1:])
				if err != nil {
					fmt.Printf("ERROR: could not parse command line arguments: %s", err)
					os.Exit(1)
				}
			}
		}
	})
}

var testcaseIds []string

// TestCase works as It, but force you to use an extra id to globally uniquely tag a testcase.
// you should focus a test ONLY BY `ginkgo -focus "#<test id>#"`, always with the two hashtags.
//
// check out testcase/examples/dsl.go for examples.
func TestCase(text string, id string, body func(), timeout ...float64) bool {
	for _, e := range testcaseIds {
		if e == id {
			panic(fmt.Sprintf("id %s should be globally unique, but duplicates found.", id))
		}
	}
	testcaseIds = append(testcaseIds, id)

	return ginkgo.It(fmt.Sprintf("%s #%s#", text, id), body, timeout...)
}
