package experiment

import (
	"context"
	"fmt"
	"time"

	"github.com/juju/errors"
	"github.com/pingcap/schrodinger/config"
	"github.com/pingcap/schrodinger/manager/template"
	"github.com/pingcap/schrodinger/manager/test"
	"github.com/pingcap/schrodinger/pkg/types"
	"github.com/pingcap/schrodinger/util"
)

var (
	errContextAborted = errors.New("aborted by context")
)

func waitTillFinish(ctx context.Context, cs *test.Test) error {
	syncTicker := time.NewTicker(config.GetGlobalConfig().Test.SyncInterval.Duration)
	expirer := time.NewTicker(config.GetGlobalConfig().Test.Expirer.Duration)
	defer func() {
		expirer.Stop()
		syncTicker.Stop()
	}()

	for {
		select {
		case <-syncTicker.C:
			if cs.IsError() {
				return errors.Errorf("(%s) case state error", cs.Name())
			}
			if cs.IsFinished() {
				return nil
			}

		case <-expirer.C:
			return errors.Errorf("(%s) case expired !", cs.Name())
		case <-ctx.Done():
			return errContextAborted
		}
	}
}

func genCatNamespace(experiment *types.ExperimentProcess) string {
	return fmt.Sprintf("%s-cat%d-tidb-cluster", experiment.Name, experiment.CatCount)
}

func genReport(experiment *Experiment) (string, error) {
	return template.GenerateReport(template.BriefReportTemplateName, template.BriefReportTemplate, experiment.process.Report)
}

func genBenchReport(experiment *Experiment) (string, error) {
	return template.GenerateReport(template.BenchReportTemplateName, template.BenchReportTemplate, experiment.process.Report)
}

func genExperimentLabels(labStr string) map[string]string {
	labels := util.GenLabels(labStr)
	if node, ok := labels["node"]; !ok || util.IsEmpty(node) {
		labels["node"] = types.DefaultNodeLabel
	}

	return labels
}
