package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime"
	"time"
)

// envelope keeps JSON responses consistent.
type envelope map[string]any

func main() {
	host := getenv("HOST", "0.0.0.0")
	port := getenv("PORT", "9292")

	mux := http.NewServeMux()
	mux.HandleFunc("/", rootHandler)
	mux.HandleFunc("/api/health", healthHandler)
	// 拆分的细粒度API端点
	mux.HandleFunc("/api/metrics/cpu", cpuMetricsHandler)
	mux.HandleFunc("/api/metrics/memory", memoryMetricsHandler)
	mux.HandleFunc("/api/metrics/storage", storageMetricsHandler)
	mux.HandleFunc("/api/metrics/gpu", gpuMetricsHandler)
	mux.HandleFunc("/api/metrics/network", networkMetricsHandler)
	mux.HandleFunc("/api/metrics/system", systemMetricsHandler)
	mux.HandleFunc("/api/metrics/docker", dockerMetricsHandler)
	mux.HandleFunc("/api/metrics/latency", latencyMetricsHandler)

	srv := &http.Server{
		Addr:              fmt.Sprintf("%s:%s", host, port),
		Handler:           loggingMiddleware(corsMiddleware(mux)),
		ReadHeaderTimeout: 5 * time.Second,
	}

	log.Printf("server starting on http://%s:%s", host, port)
	if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		log.Fatalf("server error: %v", err)
	}
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	respondJSON(w, http.StatusOK, envelope{
		"service": "萌芽监控面板 API",
		"version": "1.0.0",
		"endpoints": []map[string]string{
			{
				"path":        "/",
				"description": "API 信息和可用端点列表",
			},
			{
				"path":        "/api/health",
				"description": "健康检查",
			},
			{
				"path":        "/api/metrics/cpu",
				"description": "获取 CPU 监控数据",
			},
			{
				"path":        "/api/metrics/memory",
				"description": "获取内存监控数据",
			},
			{
				"path":        "/api/metrics/storage",
				"description": "获取存储监控数据",
			},
			{
				"path":        "/api/metrics/gpu",
				"description": "获取 GPU 监控数据",
			},
			{
				"path":        "/api/metrics/network",
				"description": "获取网络接口监控数据",
			},
			{
				"path":        "/api/metrics/system",
				"description": "获取系统统计信息（进程、包、磁盘速度等）",
			},
			{
				"path":        "/api/metrics/docker",
				"description": "获取 Docker 容器监控数据",
			},
		},
	})
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
	respondJSON(w, http.StatusOK, envelope{
		"status":    "ok",
		"timestamp": time.Now().UTC(),
	})
}

// CPU监控数据
func cpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
	cpuModel := firstMatchInFile("/proc/cpuinfo", "model name")
	cpuUsage, err := readCPUUsage()
	if err != nil {
		cpuUsage = 0
	}
	cpuTemp := readCPUTemperature()
	perCoreUsage := readPerCoreUsage()
	loads := readLoadAverages()

	cores := runtime.NumCPU()
	respondJSON(w, http.StatusOK, envelope{
		"data": CPUMetrics{
			Model:        cpuModel,
			Cores:        cores,
			UsagePercent: round(cpuUsage, 2),
			LoadAverages: loads,
			Temperature:  cpuTemp,
			PerCoreUsage: perCoreUsage,
		},
	})
}

// 内存监控数据
func memoryMetricsHandler(w http.ResponseWriter, r *http.Request) {
	mem, err := readMemory()
	if err != nil {
		respondJSON(w, http.StatusInternalServerError, envelope{
			"error": "failed to read memory",
		})
		return
	}
	respondJSON(w, http.StatusOK, envelope{
		"data": mem,
	})
}

// 存储监控数据
func storageMetricsHandler(w http.ResponseWriter, r *http.Request) {
	storage, err := readAllStorage()
	if err != nil {
		respondJSON(w, http.StatusInternalServerError, envelope{
			"error": "failed to read storage",
		})
		return
	}
	respondJSON(w, http.StatusOK, envelope{
		"data": storage,
	})
}

// GPU监控数据
func gpuMetricsHandler(w http.ResponseWriter, r *http.Request) {
	gpu := readGPU()
	respondJSON(w, http.StatusOK, envelope{
		"data": gpu,
	})
}

// 网络监控数据
func networkMetricsHandler(w http.ResponseWriter, r *http.Request) {
	network := readNetworkInterfaces()
	respondJSON(w, http.StatusOK, envelope{
		"data": network,
	})
}

// 系统统计信息
func systemMetricsHandler(w http.ResponseWriter, r *http.Request) {
	stats := readSystemStats()
	
	// 读取系统基本信息
	hostname, _ := os.Hostname()
	osInfo := readOSInfo()
	uptime := readUptime()
	
	// 计算总网络速度（汇总所有接口）
	networkInterfaces := readNetworkInterfaces()
	var totalRxSpeed, totalTxSpeed float64
	for _, iface := range networkInterfaces {
		totalRxSpeed += iface.RxSpeed // bytes/s
		totalTxSpeed += iface.TxSpeed // bytes/s
	}
	// 转换为 MB/s
	stats.NetworkRxSpeed = round(totalRxSpeed/1024/1024, 2)
	stats.NetworkTxSpeed = round(totalTxSpeed/1024/1024, 2)
	
	respondJSON(w, http.StatusOK, envelope{
		"data": map[string]interface{}{
			"hostname":      hostname,
			"os":            osInfo,
			"uptimeSeconds": uptime,
			"processCount":  stats.ProcessCount,
			"packageCount":  stats.PackageCount,
			"packageManager": stats.PackageManager,
			"temperature":   stats.Temperature,
			"diskReadSpeed": stats.DiskReadSpeed,
			"diskWriteSpeed": stats.DiskWriteSpeed,
			"networkRxSpeed": stats.NetworkRxSpeed,
			"networkTxSpeed": stats.NetworkTxSpeed,
			"topProcesses":  stats.TopProcesses,
			"systemLogs":    stats.SystemLogs,
		},
	})
}

// Docker监控数据
func dockerMetricsHandler(w http.ResponseWriter, r *http.Request) {
	docker := readDockerStats()
	respondJSON(w, http.StatusOK, envelope{
		"data": docker,
	})
}

// 延迟监控数据
func latencyMetricsHandler(w http.ResponseWriter, r *http.Request) {
	// 记录请求开始时间，用于计算客户端到服务器的延迟
	startTime := time.Now()
	
	// 读取外部网站延迟
	externalLatencies := readExternalLatencies()
	
	// 计算服务器处理时间（这个可以作为参考，实际客户端延迟由前端计算）
	serverProcessTime := time.Since(startTime).Milliseconds()
	
	respondJSON(w, http.StatusOK, envelope{
		"data": map[string]interface{}{
			"serverProcessTime": serverProcessTime, // 服务器处理时间（参考）
			"external":          externalLatencies,
		},
	})
}

func respondJSON(w http.ResponseWriter, status int, body envelope) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	if err := json.NewEncoder(w).Encode(body); err != nil {
		log.Printf("write json error: %v", err)
	}
}

func getenv(key, fallback string) string {
	if v, ok := os.LookupEnv(key); ok && v != "" {
		return v
	}
	return fallback
}

func loggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		next.ServeHTTP(w, r)
		log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
	})
}

func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusNoContent)
			return
		}
		next.ServeHTTP(w, r)
	})
}
