package main

import (
	"sync"
	"time"

	"github.com/juju/errors"
	"github.com/pingcap/schrodinger-test/util"
	"github.com/pingcap/schrodinger/pkg/test_client"
)

type stopMode string

// stopMode
const (
	KILL stopMode = "KILL"
	DOWN stopMode = "DOWN"
)

type nemesis struct {
	sync.RWMutex
	importer  string
	lightning string
}

func newNemesis(importer, lighting string) *nemesis {
	return &nemesis{
		importer:  importer,
		lightning: lighting,
	}
}

func (n *nemesis) stopImporter(mode stopMode) error {
	n.Lock()
	defer n.Unlock()
	client.Infof("stop importer %s", n.importer)
	switch mode {
	case KILL:
		return errors.Trace(n.killImporter())
	case DOWN:
		return errors.Trace(util.DownProcess(n.importer, "tikv-importer"))
	}

	return nil
}

func (n *nemesis) killImporter() error {
	err := util.StopProcess(n.importer, "tikv-importer")
	if err != nil {
		return errors.Trace(err)
	}

	return errors.Trace(err)
}

func (n *nemesis) startImporter() error {
	n.Lock()
	defer n.Unlock()
	client.Infof("start importer %s", n.importer)

	err := util.StartProcess(n.importer, "tikv-importer")
	if err != nil {
		return errors.Trace(err)
	}

	time.Sleep(1 * time.Minute)

	err = util.AgentExec(n.lightning, "/tidb-lightning/bin/tidb-lightning-ctl -config /tidb-lightning.toml --checkpoint-error-destroy=all")

	if err != nil {
		return errors.Trace(err)
	}

	time.Sleep(1 * time.Minute)

	return errors.Trace(util.StartProcess(n.lightning, "tidb-lightning"))
}

func (n *nemesis) stopLightning(mode stopMode) error {
	n.Lock()
	defer n.Unlock()
	client.Infof("stop lightning %s", n.lightning)
	switch mode {
	case KILL:
		return errors.Trace(n.killLightning())
	case DOWN:
		return errors.Trace(util.DownProcess(n.lightning, "tidb-lightning"))
	}

	return nil
}

func (n *nemesis) killLightning() error {
	err := util.StopProcess(n.lightning, "tidb-lightning")
	if err != nil {
		return errors.Trace(err)
	}

	err = util.AgentExec(n.lightning, "/tidb-lightning/bin/tidb-lightning-ctl -config /tidb-lightning.toml --checkpoint-error-destroy=all")
	return errors.Trace(err)
}

func (n *nemesis) startLightning() error {
	n.Lock()
	defer n.Unlock()
	client.Infof("start lightning %s", n.lightning)

	return errors.Trace(util.StartProcess(n.lightning, "tidb-lightning"))
}
