package client

import (
	"encoding/json"
	"fmt"
	"os/exec"
	"strings"
	"time"

	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/zlog"
	"github.com/aceld/zinx/znet"
)

type OpenNativeRenderRouter struct {
	znet.BaseRouter
}

func (*OpenNativeRenderRouter) PreHandle(request ziface.IRequest) {
	fmt.Println("client handle start...")
	zlog.Ins().DebugF("recv from client : msgId=%d, data=%+v, len=%d", request.GetMsgID(), string(request.GetData()), len(request.GetData()))
}

type StartNativeRenderReq struct {
	RoomId int    `json:"roomId"`
	Url    string `json:"url"`
}

func (*OpenNativeRenderRouter) Handle(request ziface.IRequest) {
	// 获取roomId
	data := request.GetData()
	params := strings.Split(string(data), ":")
	if len(params) != 2 {
		zlog.Error("参数不正确")
		return
	}
	nativeRenderReq := &StartNativeRenderReq{}
	err := json.Unmarshal(data, &nativeRenderReq)
	zlog.Error(err)

	// !这里没有deviceId native render如何知道自己属于哪个设备？因为此时room中并没有nr.device
	go openNativeRender(fmt.Sprintf("%d", nativeRenderReq.RoomId), nativeRenderReq.Url, request.GetConnection())

}

type OpenNativeRenderState struct {
	DeviceId string
	RoomId   int
	Error    string
}

func openNativeRender(roomId, url string, conn ziface.IConnection) {

	conn.SendMsg(OPEN_NATIVE_RENDER_START, []byte("open native render start"))
	// 下载url文件
	time.Sleep(5 * time.Second)

	restartTiem := 0

	for {
		// 打开应用
		code, err := openRenderFile("./native-render.exe", []string{
			"--file",
			url,
			"--roomId",
			roomId,
		})
		if err != nil {
			// 非正常退出
			if code != 0 {
				// 发送消息给服务端提示启动失败
				conn.SendMsg(OPEN_NATIVE_RENDER_FAIL, []byte(err.Error()))
				fmt.Println(err)
				// 重试
				restartTiem += 1
				if restartTiem > 3 {
					break
				}
			}

		} else {
			break

		}

		//判断是正常退出还是异常退出 0- 正常退出 != 0异常退出
	}
}

func openRenderFile(cmdPath string, args []string) (int, error) {
	cmd := exec.Command(cmdPath, args...)

	// 运行命令并捕获输出
	err := cmd.Run()
	if err != nil {
		return -1, err
	}

	err = cmd.Wait()
	if err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			// 获取退出码
			exitCode := exitError.ExitCode()
			return exitCode, err
		}
		return -1, err
	}

	return -1, nil
}
