package utils

import (
	"context"
	"errors"
	"github.com/sirupsen/logrus"
	"os/exec"
	"strings"
	"time"
)

var hdc string

func init() {
	if hdc, _ = exec.LookPath("hdc"); hdc == "" {
		hdc, _ = exec.LookPath("hdc_std")
	}
	if hdc == "" {
		logrus.Panicf("can not find 'hdc', please install")
	}
}

func WaitHDC(device string, ctx context.Context) bool {
	ctx, cancelFn := context.WithTimeout(ctx, 20*time.Second)
	defer cancelFn()
	for {
		select {
		case <-ctx.Done():
			return false
		default:
		}
		ExecContext(ctx, hdc, "kill")
		time.Sleep(time.Second)
		ExecContext(ctx, hdc, "start")
		time.Sleep(time.Second)
		out, err := ExecCombinedOutputContext(ctx, hdc, "list", "targets")
		if err != nil {
			if errors.Is(err, context.Canceled) {
				return false
			}
			logrus.Errorf("failed to list hdc targets: %s, %s", string(out), err)
			continue
		}
		lines := strings.Fields(string(out))
		for _, dev := range lines {
			if dev == "[Empty]" {
				logrus.Warn("can not find any hdc targets")
				break
			}
			if device == "" || dev == device {
				return true
			}
		}
		logrus.Infof("%s not found", device)
	}
}

func TryRebootToLoader(device string, ctx context.Context) error {
	logrus.Infof("try to reboot %s to loader...", device)
	defer time.Sleep(5 * time.Second)
	if connected := WaitHDC(device, ctx); connected {
		if device == "" {
			return ExecContext(ctx, hdc, "shell", "reboot", "loader")
		} else {
			return ExecContext(ctx, hdc, "-t", device, "shell", "reboot", "loader")
		}
	}
	if err := ctx.Err(); err != nil {
		return err
	}
	logrus.Warn("can not find target hdc device, assume it has been in loader mode")
	return nil
}

func HdcShell(cmd, device string, ctx context.Context) error {
	if device == "" {
		return ExecContext(ctx, hdc, "shell", cmd)
	} else {
		return ExecContext(ctx, hdc, "-t", device, "shell", cmd)
	}
}