package psnet

import (
	"fmt"
	"net"
	"net/http"
	"time"

	"nms_nbi/lib/core/utils/ctx"
	"nms_nbi/lib/log"
	"nms_nbi/lib/services"
	"nms_nbi/lib/wsinfo"
	"nms_nbi/restagent/config"

	"github.com/gorilla/websocket"
	"github.com/shirou/gopsutil/process"
)

var (
	// websockte通信
	UriWs = config.DefaultUriPrefix + "/monitor/{apiVersion}/psnet/ws"
	// 停止进程
	UriStop = config.DefaultUriPrefix + "/monitor/{apiVersion}/psnet/stop"

	// 检查ip端口请求
	UriPing = config.DefaultUriPrefix + "/monitor/{apiVersion}/psnet/ping"
)

// 进程管理
var wsUpgrade = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// ProcessWs
func ProcessWs(w http.ResponseWriter, r *http.Request) {
	ws, err := wsUpgrade.Upgrade(w, r, nil)
	if err != nil {
		return
	}
	wsClient := wsinfo.NewWsClient("processClient", ws)
	go wsClient.Read()
	go wsClient.Write()
}

// 停止进程 {"PID":30040}
func StopProcess(w http.ResponseWriter, r *http.Request) {
	// json 請求參數獲取
	var bodyArgs struct {
		PID int32 `json:"PID"  validate:"required"`
	}
	err := ctx.ShouldBindJSON(r, &bodyArgs)
	if err != nil {
		log.Error("io.ReadAll is failed:", err)
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}

	proc, err := process.NewProcess(bodyArgs.PID)
	if err != nil {
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}
	if err := proc.Kill(); err != nil {
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}
	services.ResponseStatusOK200Null(w)
}

// 检查ip端口请求
func Ping(w http.ResponseWriter, r *http.Request) {
	// json 請求參數獲取
	var bodyArgs struct {
		Host string `json:"host"  validate:"required"`
		Port string `json:"port"  validate:"required"`
	}
	err := ctx.ShouldBindJSON(r, &bodyArgs)
	if err != nil {
		log.Error("io.ReadAll is failed:", err)
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}

	conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%s", bodyArgs.Host, bodyArgs.Port), 3*time.Second)
	if err != nil {
		services.ResponseErrorWithJson(w, 400, err.Error())
		return
	}
	defer conn.Close()
	services.ResponseStatusOK200Null(w)

}
