package steps

import (
	"context"
	"fmt"
	"path/filepath"
	"strings"
	"time"

	"github.com/pingcap/errors"
	"github.com/pingcap/log"
	"github.com/pingcap/test-infra/caselib/pkg/host"
	"github.com/pingcap/test-infra/caselib/pkg/utils"
	apiresource "github.com/pingcap/test-infra/common/model/resource"
	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
	"go.uber.org/zap"

	// . "github.com/pingcap/test-infra/sdk/core"
	// . "github.com/pingcap/test-infra/sdk/resource"
	_ "github.com/pingcap/test-infra/sdk/resource/impl/k8s" //register k8s impl
)

// var TimeoutErr = errors.New("Exec command timeout")

type startBinlogReparo struct {
	drainer   *apiresource.ResourceHandle
	cfgString string
}

func NewStartBinlogReparo(drainer *apiresource.ResourceHandle, cfgString string) Step {
	return &startBinlogReparo{
		drainer:   drainer,
		cfgString: cfgString,
	}
}

func (c *startBinlogReparo) Execute(ctx context.Context) error {
	filePath := "/tmp/config.toml"
	cmd := "mkdir -p " + filepath.Dir(filePath)
	cmd += " && touch " + filePath
	cmd += " && echo \"" + strings.ReplaceAll(c.cfgString, "\"", "\\\"") + "\" >" + filePath
	wl := utils.Try(core.ResolveResourceHandle(c.drainer)).(resource.TiDBDrainer)
	drainerHost := host.NewDrainerHost(wl)
	o, err := drainerHost.Exec(cmd, 30*time.Minute)
	if err == TimeoutErr {
		return errors.Trace(err)
	}
	if o.Stderr != "" {
		log.Error("run workload", zap.String("stderr", o.Stderr))
	}
	// satrt reparo
	reparoCMD := "nohup /reparo --config /tmp/config.toml &"
	t, _ := drainerHost.Exec(reparoCMD, 60*time.Minute)
	if t.Stderr != "" {
		log.Error("run workload", zap.String("stderr", o.Stderr))
	}
	return nil
}

func (c *startBinlogReparo) String() string {
	return fmt.Sprintf("start reparo")
}

func (b *Builder) StartBinlogReparo(drainer *apiresource.ResourceHandle, cfgString string) *Builder {
	b.steps = append(b.steps, NewStartBinlogReparo(drainer, cfgString))
	return b
}
