package collector

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

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

func TestCollectRedfishLogEntries_UsesLinkedManagerLogServicesPath(t *testing.T) {
	mux := http.NewServeMux()
	register := func(path string, payload interface{}) {
		mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Content-Type", "application/json")
			_ = json.NewEncoder(w).Encode(payload)
		})
	}

	register("/redfish/v1/Managers/1", map[string]interface{}{
		"Id": "1",
		"LogServices": map[string]interface{}{
			"@odata.id": "/redfish/v1/Systems/1/LogServices",
		},
	})
	register("/redfish/v1/Systems/1/LogServices", map[string]interface{}{
		"Members": []map[string]string{
			{"@odata.id": "/redfish/v1/Systems/1/LogServices/SEL"},
		},
	})
	register("/redfish/v1/Systems/1/LogServices/SEL", map[string]interface{}{
		"Id": "SEL",
		"Entries": map[string]interface{}{
			"@odata.id": "/redfish/v1/Systems/1/LogServices/SEL/Entries",
		},
	})
	register("/redfish/v1/Systems/1/LogServices/SEL/Entries", map[string]interface{}{
		"Members": []map[string]string{
			{"@odata.id": "/redfish/v1/Systems/1/LogServices/SEL/Entries/1"},
		},
	})
	register("/redfish/v1/Systems/1/LogServices/SEL/Entries/1", map[string]interface{}{
		"Id":              "1",
		"Created":         time.Now().UTC().Format(time.RFC3339),
		"Message":         "System found Unqualified DIMM in slot DIMM A1",
		"MessageSeverity": "OK",
		"SensorType":      "Memory",
		"EntryType":       "Event",
	})

	ts := httptest.NewServer(mux)
	defer ts.Close()

	c := NewRedfishConnector()
	got := c.collectRedfishLogEntries(context.Background(), ts.Client(), Request{
		Host:     ts.URL,
		Port:     443,
		Protocol: "redfish",
		Username: "admin",
		AuthType: "password",
		Password: "secret",
		TLSMode:  "strict",
	}, ts.URL, nil, []string{"/redfish/v1/Managers/1"})

	if len(got) != 1 {
		t.Fatalf("expected 1 collected log entry, got %d", len(got))
	}
	if got[0]["Message"] != "System found Unqualified DIMM in slot DIMM A1" {
		t.Fatalf("unexpected collected message: %#v", got[0]["Message"])
	}
}

func TestParseRedfishLogEntries_UnqualifiedDIMMBecomesWarning(t *testing.T) {
	rawPayloads := map[string]any{
		"redfish_log_entries": []any{
			map[string]any{
				"Id":              "sel-1",
				"Created":         "2026-04-13T12:00:00Z",
				"Message":         "System found Unqualified DIMM in slot DIMM A1",
				"MessageSeverity": "OK",
				"SensorType":      "Memory",
				"EntryType":       "Event",
			},
		},
	}

	events := parseRedfishLogEntries(rawPayloads, time.Date(2026, 4, 13, 12, 30, 0, 0, time.UTC))
	if len(events) != 1 {
		t.Fatalf("expected 1 event, got %d", len(events))
	}
	if events[0].Severity != models.SeverityWarning {
		t.Fatalf("expected warning severity, got %q", events[0].Severity)
	}
	if events[0].Description != "System found Unqualified DIMM in slot DIMM A1" {
		t.Fatalf("unexpected description: %q", events[0].Description)
	}
}

func TestParseRedfishLogEntries_LenovoOEMEntryIsKept(t *testing.T) {
	rawPayloads := map[string]any{
		"redfish_log_entries": []any{
			map[string]any{
				"Id":              "plat-55",
				"Created":         "2026-04-13T12:00:00Z",
				"Message":         "DIMM A1 is unqualified",
				"MessageSeverity": "Warning",
				"SensorType":      "Memory",
				"EntryType":       "Oem",
				"OemRecordFormat": "Lenovo",
				"EntryCode":       "Assert",
			},
		},
	}

	events := parseRedfishLogEntries(rawPayloads, time.Date(2026, 4, 13, 12, 30, 0, 0, time.UTC))
	if len(events) != 1 {
		t.Fatalf("expected 1 Lenovo OEM event, got %d", len(events))
	}
	if events[0].Severity != models.SeverityWarning {
		t.Fatalf("expected warning severity, got %q", events[0].Severity)
	}
}
