// 已不使用此功能 改用脚本定时检测上报

package jobs

import (
	"context"
	"fmt"
	"gadmin/config"
	"gadmin/internal/admin/consts"
	"gadmin/internal/admin/library/docker"
	"gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/go-resty/resty/v2"
	"github.com/sirupsen/logrus"
)

var GameAlarm = new(jGameAlarm)

type jGameAlarm struct {
	sync.RWMutex
}

func (j *jGameAlarm) Run() {
	logrus.Info("jGameAlarm Run.....")
	if os.Getenv("GIN_MODE") == "release" || os.Getenv("ADMIN_IS_LOCAL") == "1" {
		j.handle()
	} else {
		logrus.Warn("非正式环境无需报警，跳过..")
	}
}

func (j *jGameAlarm) handle() {
	j.RLock()
	defer j.RUnlock()

	var (
		ctx   = context.TODO()
		q     = query.Use(config.DB).ServerDeploy
		m     = q.WithContext(ctx).Where(q.Environment.Eq("release")).Where(q.AlarmSwitch.Eq(1)) // 只监测正式服
		lists []*model.ServerDeploy
	)

	m = m.Order(q.ID.Desc())

	count, err := m.Count()
	if err != nil {
		logrus.Warnf("GameAlarm count err:%+v", err)
		return
	}

	if count > 0 {
		if err = m.Scan(&lists); err != nil {
			logrus.Warnf("GameAlarm Scan err:%+v", err)
			return
		}
	}

	if len(lists) == 0 {
		logrus.Warnf("GameAlarm 没有找到需要监测的服务器..")
		return
	}

	for _, v := range lists {
		var monitor = make(map[string]bool)

		if consts.DeployTypeGrave == v.ServerType {
			monitor = map[string]bool{
				"./archive": false,
				// "./chapter": false,
				"./chapterd": false,
				//"./gate":     false,
				"./store": false,
				"./world": false,
			}
		}

		if consts.DeployTypeLogin == v.ServerType {
			monitor = map[string]bool{
				"./login": false,
			}
		}

		// if consts.DeployTypeGate == v.ServerType {
		// 	monitor = map[string]bool{
		// 		"./gate": false,
		// 	}
		// }

		if len(monitor) == 0 {
			logrus.Warn("GameAlarm monitor is not set")
			continue
		}

		process, err := docker.RetryGraveProcess(docker.GraveProcessInput{Ctx: ctx, Deploy: v}, 5, 0)
		if err != nil {
			logrus.Warnf("GameAlarm RetryGraveProcess err:%+v", err)
			msg := fmt.Sprintf("docker通讯异常:[%v]", err.Error())
			//logrus.Warnf("GameAlarm sendAlert docker通讯异常 msg:%+v", msg)
			if err = j.sendAlert(v, "-", msg); err != nil {
				logrus.Warnf("GameAlarm sendAlert docker通讯异常 err:%+v", err)
				continue
			}
			continue
		}

		for _, s := range strings.Split(string(process), "\n") {
			awk := strings.Split(s, " ")
			if _, ok := monitor[awk[len(awk)-1]]; ok {
				monitor[awk[len(awk)-1]] = true
			}
		}

		for s, b := range monitor {
			if !b {
				ps := strings.ReplaceAll(s, "./", "")
				if err = j.sendAlert(v, ps, "离线报警"); err != nil {
					logrus.Warnf("GameAlarm sendAlert 离线报警 err:%+v", err)
					continue
				}
			}
		}

	}
}

func (j *jGameAlarm) sendAlert(deploy *model.ServerDeploy, ps, msg string) (err error) {
	logrus.Warnf("sendAlert deploy：%+v, ps:%v", deploy, ps)

	var (
		client = resty.New().SetDebug(true)
		url    = os.Getenv("SERVER_ALERT_URL")
		data   = `{"serverName":"%v","process":"%v","content":"%v","time":"%v"}`
	)

	_, err = client.R().
		SetHeader("Content-Type", "application/json").
		SetBody(fmt.Sprintf(data, deploy.Name, ps, msg, time.Now().Format("2006-01-02 15:04:05"))).
		Post(url)
	return
}
