// Package supermicro provides parser for Supermicro BMC crashdump archives
// Tested with: Supermicro SYS-821GE-TNHR (Crashdump format)
//
// IMPORTANT: Increment parserVersion when modifying parser logic!
// This helps track which version was used to parse specific logs.
package supermicro

import (
	"strings"

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

// parserVersion - version of this parser module
// IMPORTANT: Increment this version when making changes to parser logic!
const parserVersion = "1.0.0"

func init() {
	parser.Register(&Parser{})
}

// Parser implements VendorParser for Supermicro servers
type Parser struct{}

// Name returns human-readable parser name
func (p *Parser) Name() string {
	return "SMC Crash Dump Parser"
}

// Vendor returns vendor identifier
func (p *Parser) Vendor() string {
	return "supermicro"
}

// Version returns parser version
// IMPORTANT: Update parserVersion constant when modifying parser logic!
func (p *Parser) Version() string {
	return parserVersion
}

// Detect checks if archive matches Supermicro crashdump format
// Returns confidence 0-100
func (p *Parser) Detect(files []parser.ExtractedFile) int {
	confidence := 0

	for _, f := range files {
		path := strings.ToLower(f.Path)

		// Strong indicator for Supermicro Crashdump format
		if strings.HasSuffix(path, "cdump.txt") {
			// Check if it's really Supermicro crashdump format
			if containsCrashdumpMarkers(f.Content) {
				confidence += 80
			}
		}

		// Cap at 100
		if confidence >= 100 {
			return 100
		}
	}

	return confidence
}

// containsCrashdumpMarkers checks if content has Supermicro crashdump markers
func containsCrashdumpMarkers(content []byte) bool {
	s := string(content)
	// Check for typical Supermicro Crashdump structure
	return strings.Contains(s, "crash_data") &&
		strings.Contains(s, "METADATA") &&
		(strings.Contains(s, "bmc_fw_ver") || strings.Contains(s, "crashdump_ver"))
}

// Parse parses Supermicro crashdump archive
func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, error) {
	result := &models.AnalysisResult{
		Events:  make([]models.Event, 0),
		FRU:     make([]models.FRUInfo, 0),
		Sensors: make([]models.SensorReading, 0),
	}

	// Initialize hardware config
	result.Hardware = &models.HardwareConfig{
		CPUs: make([]models.CPU, 0),
	}

	// Parse CDump.txt (JSON crashdump)
	if f := parser.FindFileByName(files, "CDump.txt"); f != nil {
		if err := ParseCrashDump(f.Content, result); err != nil {
			// Log error but continue parsing other files
			_ = err // Ignore error for now
		}
	}

	return result, nil
}
