package infra

import (
	"os/exec"
	"runtime"
	"time"

	"github.com/adamweixuan/getty"
	"virjar.com/majora-go/log"
	"virjar.com/majora-go/model"
)

const (
	cmdWin  = "/C"
	cmdUnix = "-c"
)

func Redial(cfg *model.Configure, session getty.Session) {
	log.Run().Infof("[redial] start, session is close :%d", session.IsClosed())
	beforeIp := GetPPP()
	retry := 0
	defer func(start time.Time) {
		newIp := GetPPP()
		log.Run().Infof("[redial] retry %d, cost %v, ip change %s -> %s, session is close:%v",
			retry, time.Since(start), beforeIp, newIp, session.IsClosed())
	}(time.Now())
	for {
		retry++
		status := command(cfg)
		pingBaidu := RandomPing()
		log.Run().Infof("[redial] net check: %d->%v", retry, pingBaidu)
		if pingBaidu && status {
			break
		}
	}
}

func RedialByCheck(cfg *model.Configure) bool {
	beforeIp := GetPPP()
	defer func(start time.Time) {
		newIp := GetPPP()
		log.Run().Infof("[RedialByCheck] cost %v, ip change %s -> %s", time.Since(start), beforeIp, newIp)
	}(time.Now())
	return command(cfg)
}

func command(cfg *model.Configure) bool {
	execPath := cfg.Redial.ExecPath
	if len(execPath) == 0 {
		log.Run().Warn("[redial] exec file is empty")
		return true
	}
	command := cfg.Redial.Command
	if len(command) == 0 {
		log.Run().Warn("[redial] command is empty")
		return true
	}

	args := cmdUnix
	if runtime.GOOS == "windows" {
		args = cmdWin
	}

	cmd := exec.Command(command, args, execPath)
	output, err := cmd.Output()
	if err != nil {
		log.Run().Errorf("[redial] Execute Shell:%s failed with error:%s", command, err.Error())
		return false
	}
	log.Run().Infof("[redial] success %+v resp:%s", cmd, string(output))
	return true
}
