package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/pingcap/schrodinger/pkg/test_client"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var hclient *http.Client

func main() {
	client.Info("[tibug-53 leader move at same time] start...")
	ctx, cancel := context.WithCancel(context.Background())
	//Monitoring system exit message
	sc := make(chan os.Signal, 1)
	signal.Notify(sc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)

	go func() {
		sig := <-sc
		client.Infof("[hello world] Got signal [%s] to exist.", sig)
		cancel()
		os.Exit(0)
	}()

	cli := client.New(ctx, client.ModeOnline)
	timeout := flag.Duration("timeout", 6, "http timeout (seconds)")
	flag.Parse()
	InitHClient(*timeout)
	pds := cli.PDs()
	transferAtSameTime(pds)
}

func InitHClient(timeout time.Duration) {
	hclient = &http.Client{Timeout:timeout * time.Second}
}



func transferAtSameTime(pds []string) {
	if len(pds) == 0 {
		client.Fatal("can not achieve pd address")
	}

	client.Info(fmt.Sprintf("[tibug-53] pd addresses: %s", pds))

	pdnames := PdNames(pds[0])
	client.Info(pdnames)

	errCh := make(chan error, len(pds))

	for i, pd := range pds {
		go func(pdAddr string, pdName string) {
			err := transferPdLeader(pdAddr, pdName)
			client.Infof("transfer to %s ok, err: %v\n", pdName, err)
			errCh <- err
		}(pd, pdnames[i])
	}

	for i := 0; i < len(pds); i++ {
		err := <- errCh
		if err == nil {
			continue
		}

		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			client.Fatalf("[tibug-53] one pd client block timeout in concurrent move leader")
		}
	}

	client.Info("[tibug-53] test ok")
}

const transUrlTemplate = "http://%s/pd/api/v1/leader/transfer/%s"

func transferPdLeader(pd string, toPdName string) error {
	request, err := http.NewRequest(http.MethodPost, fmt.Sprintf(transUrlTemplate, pd, toPdName), nil)
	if err != nil {
		client.Fatalf("transfer req construct error %v \n", err)
	}

	_, err = hclient.Do(request)

	return err
}


