package status

import (
	"fmt"
	"time"
	"wdd.io/agent-go/g"
	logger2 "wdd.io/agent-go/logger"
)

var log = logger2.Log
var pool = g.G.P

type StatusMessage struct {
	/**
	  * which kind of status should be return
		 "PING";
	   * METRIC => short time message
	   * ALL => all agent status message
	  * */
	StatusType        string `json:"statusType,omitempty"`
	MetricRepeatCount int    `json:"metricRepeatCount,omitempty"`
	metricRepeatPinch int    `json:"metricRepeatPinch,omitempty"`
}

type AgentMetric struct {
	CPUMetric     *CPUMetric
	MemoryMetric  *MemoryMetric
	NetworkMetric []NetworkMetric
	DiskMetric    []DiskInfo
	DockerMetric  *DockerMetric
}

type AgentInfo struct {
	CPUInfo     *CPUInfo
	MemoryInfo  *MemoryInfo
	NetworkInfo []NetworkInfo
	DiskInfo    []DiskInfo
	HostInfo    *HostInfo
	DockerInfo  *DockerMetric
}

func Ping() string {
	return "PONG"
}

func ReportAgentMetric() *AgentMetric {

	lenOfAgentMetric := 5
	waitResultChan := make(chan string, lenOfAgentMetric)
	timeout := time.After(5 * time.Second)
	var err error

	var cpuMetric *CPUMetric
	err = pool.Submit(func() {
		cpuMetric, err = GetCPUMetric()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetCPUMetric error !"
			return
		}
		waitResultChan <- "GetCPUMetric success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentMetric] - GetCPUMetric exec error  => %v", err)
	}

	var memoryMetric *MemoryMetric
	err = pool.Submit(func() {
		memoryMetric, err = GetMemoryMetric()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetMemoryMetric error !"
			return
		}
		waitResultChan <- "GetMemoryMetric success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentMetric] - GetMemoryMetric exec error  => %v", err)
	}

	var diskInfoList []DiskInfo
	err = pool.Submit(func() {
		diskInfoList, err = GetDiskInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetDiskInfo error !"
			return
		}
		waitResultChan <- "GetDiskInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentMetric] - GetDiskInfo exec error  => %v", err)
	}

	var networkMetric []NetworkMetric
	err = pool.Submit(func() {
		networkMetric, err = GetNetworkMetric()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetNetworkMetric error !"
			return
		}
		waitResultChan <- "GetNetworkMetric success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentMetric] - GetNetworkMetric exec error  => %v", err)
	}
	var dockerMetric *DockerMetric
	err = pool.Submit(func() {
		dockerMetric, err = GetDockerMetric()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetDockerMetric error !"
			return
		}
		waitResultChan <- "GetDockerMetric success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentMetric] - GetDockerMetric exec error  => %v", err)
	}

	for i := 0; i < lenOfAgentMetric; i++ {
		select {
		case result := <-waitResultChan:
			log.DebugF("[ReportAgentMetric] - metric received => %s", result)
		case <-timeout:
			fmt.Println("[ReportAgentMetric] - Timeout! Not all results received.")
			break
		}
	}

	return &AgentMetric{
		CPUMetric:     cpuMetric,
		MemoryMetric:  memoryMetric,
		NetworkMetric: networkMetric,
		DiskMetric:    diskInfoList,
		DockerMetric:  dockerMetric,
	}

}

func ReportAgentInfo() *AgentInfo {

	lenOfAgentMetric := 6
	waitResultChan := make(chan string, lenOfAgentMetric)
	timeout := time.After(5 * time.Second)
	var err error

	var cpuInfo *CPUInfo
	err = pool.Submit(func() {
		cpuInfo, err = GetCPUInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetCPUInfo error !"
			return
		}
		waitResultChan <- "GetCPUInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - GetCPUInfo exec error  => %v", err)
	}

	var memoryInfo *MemoryInfo
	err = pool.Submit(func() {
		memoryInfo, err = GetMemoryInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetMemoryInfo error !"
			return
		}
		waitResultChan <- "GetMemoryInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - GetMemoryInfo exec error  => %v", err)
	}

	var diskInfoList []DiskInfo
	err = pool.Submit(func() {
		diskInfoList, err = GetDiskInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetDiskInfo error !"
			return
		}
		waitResultChan <- "GetDiskInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - GetDiskInfo exec error  => %v", err)
	}

	var hostInfo *HostInfo
	err = pool.Submit(func() {
		hostInfo, err = GetHostInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetHostInfo error !"
			return
		}
		waitResultChan <- "hostInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - hostInfo exec error  => %v", err)
	}

	var networkInfo []NetworkInfo
	err = pool.Submit(func() {
		networkInfo, err = GetNetworkInfo()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetNetworkInfo error !"
			return
		}
		waitResultChan <- "GetNetworkInfo success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - GetNetworkInfo exec error  => %v", err)
	}

	var dockerMetric *DockerMetric
	err = pool.Submit(func() {
		dockerMetric, err = GetDockerMetric()
		if err != nil {
			log.ErrorF("获取Agent的状态出现错误！ 请检查 => %v", err)
			waitResultChan <- "GetDockerMetric error !"
			return
		}
		waitResultChan <- "GetDockerMetric success !"
	})
	if err != nil {
		log.ErrorF("[ReportAgentInfo] - GetDockerMetric exec error  => %v", err)
	}

	for i := 0; i < lenOfAgentMetric; i++ {
		select {
		case result := <-waitResultChan:
			log.DebugF("[ReportAgentInfo] - metric received => %s", result)
		case <-timeout:
			fmt.Println("[ReportAgentInfo] - Timeout! Not all results received.")
			break
		}
	}

	return &AgentInfo{
		CPUInfo:     cpuInfo,
		MemoryInfo:  memoryInfo,
		NetworkInfo: networkInfo,
		DiskInfo:    diskInfoList,
		HostInfo:    hostInfo,
		DockerInfo:  dockerMetric,
	}

}

func ConvertToFormat(eventData float64) string {
	duration := time.Duration(eventData) * time.Second

	fmt.Println(duration)

	hours := int(duration.Hours())
	minutes := int(duration.Minutes()) % 60
	seconds := int(duration.Seconds()) % 60
	milliseconds := duration.Milliseconds() % 1000
	return fmt.Sprintf("%02d:%02d:%02d,%03d", hours, minutes, seconds, milliseconds)
}
