func (t Test) SkipEsVersion(minmax string) bool {
	return skipVersion(minmax)
}
SkipEsVersion returns true if the test should be skipped.
package gentests
import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"github.com/opensearch-project/opensearch-go/internal/build/utils"
)
var reFilename = regexp.MustCompile(`\d*_?(.+)\.ya?ml`)
var reNumber = regexp.MustCompile(`^\d+$`)
var reBaseFilename = regexp.MustCompile(`rest-api-spec/test/\w+/(.*$)`)
type TestPayload struct {
	Filepath string
	Payload  interface{}
}
type TestSuite struct {
	Dir      string
	Filepath string
	Skip     bool
	SkipInfo string
	Type     string
	Setup    []Action
	Teardown []Action
	Tests []Test
}
type Test struct {
	Name     string
	Filepath string
	OrigName string
	Skip     bool
	SkipInfo string
	Setup    []Action
	Teardown []Action
	Steps Steps
}
type Steps []Step
type Step interface{}
type Action struct {
	payload interface{}
	method  string
	params  map[interface{}]interface{}
	catch   string
	headers map[string]string
}
type Assertion struct {
	payload interface{}
	operation string
}
type Stash struct {
	payload interface{}
}
func NewTestSuite(fpath string, payloads []TestPayload) TestSuite {
	ts := TestSuite{
		Dir:      strings.Title(filepath.Base(filepath.Dir(fpath))),
		Filepath: fpath,
	}
	if ts.Type == "" {
		ts.Type = "free"
	}
	for _, payload := range payloads {
		sec_keys := utils.MapKeys(payload.Payload)
		switch {
		case len(sec_keys) > 0 && strings.Contains(strings.Join(sec_keys, ","), "setup") || strings.Contains(strings.Join(sec_keys, ","), "teardown"):
			for k, v := range payload.Payload.(map[interface{}]interface{}) {
				switch k {
				case "setup":
					for _, vv := range v.([]interface{}) {
						for k, vvv := range vv.(map[interface{}]interface{}) {
							if k == "do" {
								ts.Setup = append(ts.Setup, NewAction(vvv))
							}
						}
					}
				case "teardown":
					for _, vv := range v.([]interface{}) {
						for k, vvv := range vv.(map[interface{}]interface{}) {
							if k == "do" {
								ts.Teardown = append(ts.Teardown, NewAction(vvv))
							}
						}
					}
				}
			}
		default:
			for k, v := range payload.Payload.(map[interface{}]interface{}) {
				var t Test
				var steps []Step
				for _, vv := range v.([]interface{}) {
					switch utils.MapKeys(vv)[0] {
					case "skip":
						var (
							ok     bool
							skip_v string
							skip_r string
						)
						skip := vv.(map[interface{}]interface{})["skip"]
						if skip_v, ok = skip.(map[interface{}]interface{})["version"].(string); ok {
							if skip_rr, ok := skip.(map[interface{}]interface{})["reason"].(string); ok {
								skip_r = skip_rr
							}
							if skip_v == "all" {
								t.Skip = true
								t.SkipInfo = "Skipping all versions"
								break
							}
							if ts.SkipEsVersion(skip_v) {
								t.Skip = true
								t.SkipInfo = skip_r
							}
						}
					case "setup":
						for _, vvv := range vv.(map[interface{}]interface{}) {
							for _, vvvv := range vvv.([]interface{}) {
								t.Setup = append(t.Setup, NewAction(vvvv.(map[interface{}]interface{})["do"]))
							}
						}
					case "teardown":
						for _, vvv := range vv.(map[interface{}]interface{}) {
							for _, vvvv := range vvv.([]interface{}) {
								t.Teardown = append(t.Teardown, NewAction(vvvv.(map[interface{}]interface{})["do"]))
							}
						}
					case "set":
						for _, vvv := range vv.(map[interface{}]interface{}) {
							steps = append(steps, NewStash(vvv))
						}
					case "transform_and_set":
						for _, vvv := range vv.(map[interface{}]interface{}) {
							key := utils.MapValues(vvv)[0]
							val := utils.MapKeys(vvv)[0]
							payload := make(map[interface{}]interface{})
							payload[key] = val
							steps = append(steps, NewStash(payload))
						}
					case "do":
						for _, vvv := range vv.(map[interface{}]interface{}) {
							steps = append(steps, NewAction(vvv))
						}
					case "is_true", "is_false", "match", "lt", "gt", "lte", "gte":
						for kkk, vvv := range vv.(map[interface{}]interface{}) {
							steps = append(steps, NewAssertion(kkk.(string), vvv))
						}
					}
				}
				if !ts.Skip {
					t.Name = strings.ReplaceAll(k.(string), `"`, `'`)
					t.Filepath = payload.Filepath
					t.OrigName = k.(string)
					t.Steps = steps
					ts.Tests = append(ts.Tests, t)
				}
			}
		}
	}
	return ts
}
// NewAction returns a new action from the payload.
//
func NewAction(payload interface{}) Action {
	defer func() {
		if r := recover(); r != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", r)
			fmt.Fprintf(os.Stderr, "Payload: %v\n", payload)
		}
	}()
	var a Action
	a.payload = payload
	a.headers = make(map[string]string)
	for k, v := range payload.(map[interface{}]interface{}) {
		switch k {
		case "catch":
			a.catch = v.(string)
		case "warnings", "allowed_warnings", "allowed_warnings_regex", "node_selector", "arbitrary_key":
			continue
		case "headers":
			for kk, vv := range v.(map[interface{}]interface{}) {
				a.headers[kk.(string)] = vv.(string)
			}
		default:
			a.method = k.(string)
			a.params = v.(map[interface{}]interface{})
		}
	}
	return a
}
// NewAssertion returns a new assertion from the payload.
//
func NewAssertion(operation string, payload interface{}) Assertion {
	return Assertion{operation: operation, payload: payload}
}
// NewStash returns a new stash from the payload.
//
func NewStash(payload interface{}) Stash {
	return Stash{payload: payload}
}
// Name returns a human name for the test suite.
//
func (ts TestSuite) Name() string {
	var b strings.Builder
	for _, v := range strings.Split(ts.Dir, ".") {
		b.WriteString(strings.Title(v))
	}
	bname := reFilename.ReplaceAllString(filepath.Base(ts.Filepath), "$1")
	for _, v := range strings.Split(bname, "_") {
		b.WriteString(strings.Title(v))
	}
	return strings.ReplaceAll(b.String(), "-", "")
}
// Filename returns a suitable filename for the test suite.
//
func (ts TestSuite) Filename() string {
	var b strings.Builder
	b.WriteString(strings.ToLower(strings.Replace(ts.Dir, ".", "_", -1)))
	b.WriteString("__")
	bname := reFilename.ReplaceAllString(filepath.Base(ts.Filepath), "$1")
	b.WriteString(strings.ToLower(bname))
	return b.String()
}
// SkipEsVersion returns true if the test suite should be skipped.
//
func (ts TestSuite) SkipEsVersion(minmax string) bool {
	return skipVersion(minmax)
}
// BaseFilename extracts and returns the test filename in form of `foo/bar/10_qux.yml`.
//
func (t Test) BaseFilename() string {
	parts := reBaseFilename.FindStringSubmatch(t.Filepath)
	if len(parts) < 1 {
		panic(fmt.Sprintf("Unexpected parts for path [%s]: %s", t.Filepath, parts))
	}
	return strings.TrimPrefix(parts[1], string(filepath.Separator))
}