package nvidia_bug_report

import (
	"bufio"
	"regexp"
	"strconv"
	"strings"

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

// parseNetworkAdapters extracts network adapter information from lspci output
func parseNetworkAdapters(content string, result *models.AnalysisResult) {
	scanner := bufio.NewScanner(strings.NewReader(content))

	var currentAdapter *models.NetworkAdapter
	inVPD := false
	currentBDF := ""

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

		// Check if this is a new PCI device line
		re := regexp.MustCompile(`^([\da-f]{4}:[\da-f]{2}:[\da-f]{2}\.[\da-f])\s+`)
		matches := re.FindStringSubmatch(line)

		if len(matches) > 0 {
			// Save previous adapter if exists before processing new device
			if currentAdapter != nil && currentAdapter.Model != "" {
				result.Hardware.NetworkAdapters = append(result.Hardware.NetworkAdapters, *currentAdapter)
			}
			currentAdapter = nil
			inVPD = false
		}

		// Match PCI device line: "0000:1f:00.0 Ethernet controller [0200]: Mellanox Technologies..."
		if strings.Contains(line, "Ethernet controller") || strings.Contains(line, "Network controller") || strings.Contains(line, "Infiniband controller") {
			// Extract BDF (Bus:Device.Function)
			if len(matches) > 1 {
				currentBDF = matches[1]
				currentAdapter = &models.NetworkAdapter{
					Location: currentBDF,
					Present:  true,
				}

				// Extract vendor and device info
				// Format: "Vendor description [DeviceClass]: Vendor Name Device Name [VendorID:DeviceID]"
				re2 := regexp.MustCompile(`:\s+(.+?)\s+\[([0-9a-f]{4}):([0-9a-f]{4})\]`)
				matches2 := re2.FindStringSubmatch(line)
				if len(matches2) > 3 {
					// Parse vendor name from description
					vendorDesc := matches2[1]
					if idx := strings.Index(vendorDesc, " "); idx > 0 {
						currentAdapter.Vendor = strings.Split(vendorDesc, " ")[0]
					}

					// Parse vendor ID and device ID
					if vendorID, err := strconv.ParseInt(matches2[2], 16, 32); err == nil {
						currentAdapter.VendorID = int(vendorID)
					}
					if deviceID, err := strconv.ParseInt(matches2[3], 16, 32); err == nil {
						currentAdapter.DeviceID = int(deviceID)
					}
				}
				continue
			}
		}

		// Skip if not processing an adapter
		if currentAdapter == nil {
			continue
		}

		// Parse Physical Slot
		if strings.HasPrefix(trimmed, "Physical Slot:") {
			slotStr := strings.TrimPrefix(trimmed, "Physical Slot:")
			currentAdapter.Slot = strings.TrimSpace(slotStr)
			continue
		}

		// Start of Vital Product Data section
		if strings.Contains(trimmed, "Vital Product Data") {
			inVPD = true
			continue
		}

		// End of VPD section
		if inVPD && (trimmed == "End" || strings.HasPrefix(trimmed, "Capabilities:")) {
			if trimmed == "End" {
				inVPD = false
			}
			continue
		}

		// Parse Product Name in VPD
		if inVPD && strings.HasPrefix(trimmed, "Product Name:") {
			productName := strings.TrimPrefix(trimmed, "Product Name:")
			currentAdapter.Model = strings.TrimSpace(productName)

			// Extract port count from model name
			if strings.Contains(currentAdapter.Model, "Dual-port") {
				currentAdapter.PortCount = 2
			} else if strings.Contains(currentAdapter.Model, "Single-port") {
				currentAdapter.PortCount = 1
			} else if strings.Contains(currentAdapter.Model, "Quad-port") {
				currentAdapter.PortCount = 4
			}

			// Extract port type from model name
			if strings.Contains(currentAdapter.Model, "QSFP56") {
				currentAdapter.PortType = "QSFP56"
			} else if strings.Contains(currentAdapter.Model, "QSFP28") {
				currentAdapter.PortType = "QSFP28"
			} else if strings.Contains(currentAdapter.Model, "OSFP") {
				currentAdapter.PortType = "OSFP"
			} else if strings.Contains(currentAdapter.Model, "SFP") {
				currentAdapter.PortType = "SFP+"
			}
			continue
		}

		// Parse VPD fields
		if inVPD && strings.HasPrefix(trimmed, "[") {
			// Match pattern: [TAG] Description: Value
			re := regexp.MustCompile(`^\[([A-Z0-9]+)\]\s+([^:]+):\s+(.+)`)
			matches := re.FindStringSubmatch(trimmed)
			if len(matches) > 3 {
				tag := matches[1]
				value := strings.TrimSpace(matches[3])

				switch tag {
				case "PN":
					// Part number
					currentAdapter.PartNumber = value
				case "SN":
					// Serial number
					currentAdapter.SerialNumber = value
				case "EC":
					// Engineering changes - could be stored as firmware/revision
					if currentAdapter.Firmware == "" {
						currentAdapter.Firmware = value
					}
				}
			}
			continue
		}

		// End of current device section (empty line followed by hex dump or new device)
		if currentAdapter != nil && trimmed == "" {
			// Check if next lines are hex dump (config space)
			continue
		}
	}

	// Save last adapter if exists
	if currentAdapter != nil && currentAdapter.Model != "" {
		result.Hardware.NetworkAdapters = append(result.Hardware.NetworkAdapters, *currentAdapter)
	}
}
