package nvidia_bug_report

import (
	"bufio"
	"strconv"
	"strings"

	"git.mchus.pro/mchus/logpile/internal/models"
)

// parseCPUInfo extracts CPU information from dmidecode output
func parseCPUInfo(content string, result *models.AnalysisResult) {
	scanner := bufio.NewScanner(strings.NewReader(content))

	var currentCPU *models.CPU
	inProcessorInfo := false
	cpuSocket := 0

	for scanner.Scan() {
		line := scanner.Text()
		trimmed := strings.TrimSpace(line)

		// Start of Processor Information section
		if strings.Contains(trimmed, "Processor Information") {
			inProcessorInfo = true
			currentCPU = &models.CPU{
				Socket: cpuSocket,
			}
			cpuSocket++
			continue
		}

		// End of current section (empty line or new section with Handle)
		if inProcessorInfo && (trimmed == "" || strings.HasPrefix(trimmed, "Handle ")) {
			// Save CPU if it has valid data
			if currentCPU != nil && currentCPU.Model != "" {
				result.Hardware.CPUs = append(result.Hardware.CPUs, *currentCPU)
			}
			inProcessorInfo = false
			currentCPU = nil
			continue
		}

		// Parse fields within Processor Information section
		if inProcessorInfo && currentCPU != nil && strings.Contains(line, ":") {
			parts := strings.SplitN(trimmed, ":", 2)
			if len(parts) != 2 {
				continue
			}

			field := strings.TrimSpace(parts[0])
			value := strings.TrimSpace(parts[1])

			if value == "" || value == "Not Specified" || value == "Unknown" || value == "UNKNOWN" || value == "<OUT OF SPEC>" {
				continue
			}

			switch field {
			case "Version":
				// CPU model name
				currentCPU.Model = value
			case "Serial Number":
				currentCPU.SerialNumber = value
			case "Part Number":
				// Store part number if available
				// Could be stored in a custom field if needed
			case "Core Count":
				if cores, err := strconv.Atoi(value); err == nil {
					currentCPU.Cores = cores
				}
			case "Core Enabled":
				// Could store this if needed
			case "Thread Count":
				if threads, err := strconv.Atoi(value); err == nil {
					currentCPU.Threads = threads
				}
			case "Max Speed":
				// Parse speed like "3800 MHz"
				if speed := parseCPUSpeed(value); speed > 0 {
					currentCPU.MaxFreqMHz = speed
				}
			case "Current Speed":
				// Parse current speed like "2000 MHz"
				if speed := parseCPUSpeed(value); speed > 0 {
					currentCPU.FrequencyMHz = speed
				}
			case "Voltage":
				// Could parse voltage if needed (e.g., "1.6 V")
			case "Status":
				// Status like "Populated, Enabled"
				// Check if CPU is enabled
				if !strings.Contains(value, "Populated") {
					// Skip unpopulated CPUs
					currentCPU = nil
					inProcessorInfo = false
				}
			}
		}
	}

	// Save last CPU if exists
	if currentCPU != nil && currentCPU.Model != "" {
		result.Hardware.CPUs = append(result.Hardware.CPUs, *currentCPU)
	}
}

// parseCPUSpeed parses CPU speed strings like "3800 MHz" or "2.0 GHz"
func parseCPUSpeed(speedStr string) int {
	parts := strings.Fields(speedStr)
	if len(parts) < 2 {
		return 0
	}

	// Try to parse the number (may be int or float)
	speedStr = parts[0]
	var speed float64
	var err error

	if strings.Contains(speedStr, ".") {
		speed, err = strconv.ParseFloat(speedStr, 64)
	} else {
		var speedInt int
		speedInt, err = strconv.Atoi(speedStr)
		speed = float64(speedInt)
	}

	if err != nil {
		return 0
	}

	unit := strings.ToUpper(parts[1])
	switch unit {
	case "MHZ":
		return int(speed)
	case "GHZ":
		return int(speed * 1000)
	default:
		return 0
	}
}
