package getStateFromNE

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"

	"nms_nbi/lib/dborm"
	"nms_nbi/lib/log"
	"nms_nbi/restagent/config"
	"nms_nbi/src/framework/cron"

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

var NewProcessor = &BarProcessor{
	progress: 0,
	count:    0,
}

// bar 队列任务处理
type BarProcessor struct {
	// 任务进度
	progress int
	// 执行次数
	count int
}

type BarParams struct {
	Duration int `json:"duration"`
}

type CpuUsage struct {
	NfCpuUsage  uint16 `json:"nfCpuUsage"`
	SysCpuUsage uint16 `json:"sysCpuUsage"`
}

type MemUsage struct {
	TotalMem    uint32 `json:"totalMem"`
	NfUsedMem   uint32 `json:"nfUsedMem"`
	SysMemUsage uint16 `json:"sysMemUsage"`
}

type PartitionInfo struct {
	Total uint32 `json:"total"` // MB
	Used  uint32 `json:"used"`  // MB
}

type DiskSpace struct {
	PartitionNum uint8 `json:"partitionNum"`

	PartitionInfo []PartitionInfo `json:"partitionInfo"`
}

type SystemState struct {
	Version    string `json:"version"`
	Capability uint32 `json:"capability"`
	SerialNum  string `json:"serialNum"`
	ExpiryDate string `json:"expiryDate"`
	//Timestamp  string `json:"timestamp"`

	CpuUsage CpuUsage `json:"cpuUsage"`
	MemUsage MemUsage `json:"memUsage"`

	DiskSpace DiskSpace `json:"diskSpace"`
}

var client = resty.New()

func init() {
	client.
		SetTimeout(time.Duration(400 * time.Millisecond))
}

func (s *BarProcessor) Execute(data any) (any, error) {
	var err error

	s.count++
	options := data.(cron.JobData)
	sysJob := options.SysJob
	var params BarParams

	_ = json.Unmarshal([]byte(sysJob.TargetParams), &params)
	// if err == nil {
	// 	duration = params.Duration
	// }

	var nes []dborm.NeInfo
	_, err = dborm.XormGetAllNeInfo(&nes)
	if err != nil {
		log.Error("Failed to get all ne info:", err)
		return nil, err
	}

	failNum := 0
	succNum := 0
	for _, ne := range nes {
		requestURI := fmt.Sprintf("/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", strings.ToLower(ne.NeType))
		requestURL := fmt.Sprintf("http://%s:%s%s", ne.Ip, ne.Port, requestURI)
		log.Debug("requestURL: Get", requestURL)
		response, err := client.R().
			EnableTrace().
			SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
			SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
			Get(requestURL)
		if err != nil {
			log.Error("Failed to Get:", err)
			failNum++
			continue
		}

		log.Debug("StatusCode: ", response.StatusCode())
		switch response.StatusCode() {
		case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
			log.Trace("response body:", string(response.Body()))
			state := new(SystemState)
			_ = json.Unmarshal(response.Body(), &state)
			var dateStr *string = nil
			if state.ExpiryDate != "" && state.ExpiryDate != "-" {
				dateStr = &state.ExpiryDate
			}
			neState := new(dborm.NeState)
			neState.NeType = ne.NeType
			neState.NeId = ne.NeId
			neState.Version = state.Version
			neState.Capability = state.Capability
			neState.SerialNum = state.SerialNum
			neState.ExpiryDate = *dateStr
			cu, _ := json.Marshal(state.CpuUsage)
			neState.CpuUsage = string(cu)
			mu, _ := json.Marshal(state.MemUsage)
			neState.MemUsage = string(mu)
			ds, _ := json.Marshal(state.DiskSpace)
			neState.DiskSpace = string(ds)
			log.Trace("neState:", neState)
			_, err := dborm.XormInsertNeState(neState)
			if err != nil {
				log.Error("Failed to insert ne_state:", err)
				failNum++
				continue
			}
			succNum++
		default:
			log.Trace("response body:", string(response.Body()))
			body := new(map[string]interface{})
			_ = json.Unmarshal(response.Body(), &body)
			failNum++
		}
	}

	// 返回结果，用于记录执行结果
	return map[string]any{
		"succNum": succNum,
		"failNum": failNum,
	}, nil
}
