package chaos

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"

	"github.com/pingcap/log"
	"github.com/pingcap/test-infra/sdk/resource"
	"go.uber.org/zap"

	"github.com/pingcap/endless/pkg/client/tidb"
	"github.com/pingcap/endless/pkg/util/schedule"
	"github.com/pingcap/endless/testcase/tiflash/pkg"
)

var _ schedule.DoUndo = &FullDiskTiFLash{}

const fallocateName = "fallocate-tiflash"

// PdScheduler reload tiflash nodes without restarting them
type FullDiskTiFLash struct {
	tc          resource.TiDBCluster
	tidbCli     *tidb.Client
	currentPeer int
}

func NewFullDiskTiFLash(tc resource.TiDBCluster) (*FullDiskTiFLash, error) {
	conn, err := tc.GetDB("")
	if err != nil {
		return nil, err
	}
	return &FullDiskTiFLash{
		tc:      tc,
		tidbCli: tidb.NewClient(conn),
	}, nil
}

func (t *FullDiskTiFLash) Do() error {
	num, err := t.tidbCli.GetInstanceNum("tiflash")
	if err != nil {
		return err
	}
	t.currentPeer = rand.Intn(int(num))
	cmd := "df -m /data0 | awk '{print $4}' | tail -n1"
	stdout, err := pkg.TiFlashExecCmd(t.tc, cmd, t.currentPeer)
	if err != nil {
		return err
	}
	log.Info("current disk size(m)", zap.Int("tiflash node", t.currentPeer), zap.String("disk size", stdout))
	size, err := strconv.Atoi(strings.TrimSpace(stdout))
	if err != nil {
		return err
	}
	cmd2 := fmt.Sprintf("fallocate -l %dM /data0/%s", size-50, fallocateName)
	if _, err := pkg.TiFlashExecCmd(t.tc, cmd2, t.currentPeer); err != nil {
		return err
	}
	return nil
}

func (t *FullDiskTiFLash) Undo() error {
	cmd := fmt.Sprintf("rm -rf /data0/%s", fallocateName)
	if _, err := pkg.TiFlashExecCmd(t.tc, cmd, t.currentPeer); err != nil {
		return err
	}
	return nil
}
