package inspur

import (
	"regexp"
	"strings"
	"time"

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

// ParseIDLLog parses IDL-style entries for BMC alarms.
// Works for both plain idl.log lines and JSON structured logs (idl_json/run_json)
// where MESSAGE/LOG2_FMTMSG contains:
// |timestamp|component|type|severity|eventID|description|
func ParseIDLLog(content []byte) []models.Event {
	var events []models.Event

	// Pattern to match CommerDiagnose log entries
	// Example: |2025-12-02T17:54:27+08:00|MEMORY|Assert|Warning|0C180401|CPU1_C4D0 Memory Device Disabled...|
	re := regexp.MustCompile(`\|(\d{4}-\d{2}-\d{2}T[\d:]+[+-]\d{2}:\d{2})\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|`)

	lines := strings.Split(string(content), "\n")
	seenEvents := make(map[string]bool) // Deduplicate events

	for _, line := range lines {
		matches := re.FindStringSubmatch(line)
		if matches == nil {
			continue
		}

		timestamp := matches[1]
		component := matches[2]
		eventType := matches[3]
		severityStr := matches[4]
		eventID := matches[5]
		description := matches[6]

		// Parse timestamp
		ts, err := time.Parse("2006-01-02T15:04:05-07:00", timestamp)
		if err != nil {
			ts = time.Now()
		}

		// Map severity
		severity := mapIDLSeverity(severityStr)

		// Clean up description
		description = cleanDescription(description)

		// Create unique key for deduplication
		eventKey := eventID + "|" + description
		if seenEvents[eventKey] {
			continue
		}
		seenEvents[eventKey] = true

		// Extract sensor name from description if available
		sensorName := extractSensorName(description, component)

		events = append(events, models.Event{
			ID:          eventID,
			Timestamp:   ts,
			Source:      "BMC",
			SensorType:  strings.ToLower(component),
			SensorName:  sensorName,
			EventType:   eventType,
			Severity:    severity,
			Description: description,
		})
	}

	return events
}

func mapIDLSeverity(s string) models.Severity {
	switch strings.ToLower(s) {
	case "critical", "error":
		return models.SeverityCritical
	case "warning":
		return models.SeverityWarning
	default:
		return models.SeverityInfo
	}
}

func cleanDescription(desc string) string {
	// Remove trailing " - Assert" or similar
	desc = strings.TrimSuffix(desc, " - Assert")
	desc = strings.TrimSuffix(desc, " - Deassert")
	desc = strings.TrimSpace(desc)
	return desc
}

func extractSensorName(desc, component string) string {
	// Try to extract sensor/device name from description
	// For memory: CPU1_C4D0, CPU1_C4D1, etc.
	if component == "MEMORY" {
		re := regexp.MustCompile(`(CPU\d+_C\d+D\d+)`)
		if matches := re.FindStringSubmatch(desc); matches != nil {
			return matches[1]
		}
	}

	// For PSU: PSU0, PSU1, etc.
	if component == "PSU" || component == "POWER" {
		re := regexp.MustCompile(`(PSU\d+)`)
		if matches := re.FindStringSubmatch(desc); matches != nil {
			return matches[1]
		}
	}

	// For temperature sensors
	if component == "TEMPERATURE" || component == "THERMAL" {
		re := regexp.MustCompile(`(\w+_Temp|\w+_DTS)`)
		if matches := re.FindStringSubmatch(desc); matches != nil {
			return matches[1]
		}
	}

	return component
}
