package inspur

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

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

// SDR sensor reading patterns
var (
	sdrLineRegex = regexp.MustCompile(`^(\S+)\s+\|\s+(.+?)\s+\|\s+(\w+)$`)
	valueRegex   = regexp.MustCompile(`^([\d.]+)\s+(.+)$`)
)

// ParseSDR parses BMC SDR (Sensor Data Record) output
func ParseSDR(content []byte) []models.SensorReading {
	var readings []models.SensorReading

	scanner := bufio.NewScanner(strings.NewReader(string(content)))
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "BMC sdr Info:") {
			continue
		}

		matches := sdrLineRegex.FindStringSubmatch(line)
		if matches == nil {
			continue
		}

		name := strings.TrimSpace(matches[1])
		valueStr := strings.TrimSpace(matches[2])
		status := strings.TrimSpace(matches[3])

		reading := models.SensorReading{
			Name:   name,
			Status: status,
		}

		// Parse value and unit
		if valueStr != "disabled" && valueStr != "no reading" && !strings.HasPrefix(valueStr, "0x") {
			if vm := valueRegex.FindStringSubmatch(valueStr); vm != nil {
				if v, err := strconv.ParseFloat(vm[1], 64); err == nil {
					reading.Value = v
					reading.Unit = strings.TrimSpace(vm[2])
					reading.RawValue = valueStr // Keep original string for reference
				}
			}
		} else if strings.HasPrefix(valueStr, "0x") {
			reading.RawValue = valueStr
		}

		// Determine sensor type
		reading.Type = determineSensorType(name)

		readings = append(readings, reading)
	}

	return readings
}

func determineSensorType(name string) string {
	nameLower := strings.ToLower(name)

	switch {
	case strings.Contains(nameLower, "temp"):
		return "temperature"
	case strings.Contains(nameLower, "fan") && strings.Contains(nameLower, "speed"):
		return "fan_speed"
	case strings.Contains(nameLower, "fan") && strings.Contains(nameLower, "status"):
		return "fan_status"
	case strings.HasSuffix(nameLower, "_vin") || strings.HasSuffix(nameLower, "_vout") ||
		strings.HasSuffix(nameLower, "_v") || strings.Contains(nameLower, "volt"):
		return "voltage"
	case strings.Contains(nameLower, "power") || strings.HasSuffix(nameLower, "_pin") ||
		strings.HasSuffix(nameLower, "_pout") || strings.HasSuffix(nameLower, "_pwr"):
		return "power"
	case strings.Contains(nameLower, "psu") && strings.Contains(nameLower, "status"):
		return "psu_status"
	case strings.Contains(nameLower, "cpu") && strings.Contains(nameLower, "status"):
		return "cpu_status"
	case strings.Contains(nameLower, "hdd") || strings.Contains(nameLower, "nvme"):
		return "storage_status"
	default:
		return "other"
	}
}
