package hub

import (
	"context"
	"testing"
)

// fakeMgmtPlane is a MgmtPlaneReporter returning a fixed stanza (or nil).
type fakeMgmtPlane struct{ st *MgmtPlaneStatus }

func (f fakeMgmtPlane) MgmtPlaneStatus(context.Context) *MgmtPlaneStatus { return f.st }

func TestCollect_MgmtPlaneOmittedWhenReporterNil(t *testing.T) {
	px := &fakePx{node: "n", ns: newTestNodeStatus()}
	c := NewCollector(px, fakeProber{status: "active"}, fakeObserver{}, nil, nil, nil, "h", "0.71.0", quietLogger())
	r, err := c.Collect(context.Background())
	if err != nil {
		t.Fatalf("Collect: %v", err)
	}
	if r.MgmtPlane != nil {
		t.Fatalf("no reporter wired → mgmt_plane must be omitted (nil), got %+v", r.MgmtPlane)
	}
}

func TestCollect_MgmtPlanePopulatedWhenWired(t *testing.T) {
	px := &fakePx{node: "n", ns: newTestNodeStatus()}
	c := NewCollector(px, fakeProber{status: "active"}, fakeObserver{}, nil, nil, nil, "h", "0.71.0", quietLogger())
	c.SetMgmtPlaneReporter(fakeMgmtPlane{st: &MgmtPlaneStatus{
		PrivsepDirOK: true, SshdReachable: true, HealedRecently: true, PrivsepHealedAt: "2026-07-05T16:42:17Z",
	}})
	r, err := c.Collect(context.Background())
	if err != nil {
		t.Fatalf("Collect: %v", err)
	}
	if r.MgmtPlane == nil {
		t.Fatal("wired reporter → mgmt_plane must be present")
	}
	if !r.MgmtPlane.HealedRecently || r.MgmtPlane.PrivsepHealedAt != "2026-07-05T16:42:17Z" {
		t.Fatalf("mgmt_plane not carried through: %+v", r.MgmtPlane)
	}
}

// fakeOOB is an OOBReporter returning a fixed stanza (or nil).
type fakeOOB struct{ st *OOBStatus }

func (f fakeOOB) OOBStatus(context.Context) *OOBStatus { return f.st }

func TestCollect_OOBOmittedWhenNil(t *testing.T) {
	px := &fakePx{node: "n", ns: newTestNodeStatus()}
	c := NewCollector(px, fakeProber{status: "active"}, fakeObserver{}, nil, nil, nil, "h", "0.72.0", quietLogger())
	r, _ := c.Collect(context.Background())
	if r.OOB != nil {
		t.Fatalf("no reporter → oob omitted, got %+v", r.OOB)
	}
}

func TestCollect_OOBPopulatedWhenWired(t *testing.T) {
	px := &fakePx{node: "n", ns: newTestNodeStatus()}
	c := NewCollector(px, fakeProber{status: "active"}, fakeObserver{}, nil, nil, nil, "h", "0.72.0", quietLogger())
	c.SetOOBReporter(fakeOOB{st: &OOBStatus{FelhomSshdActive: true, FelhomSshdPort: 8822, Reachable: true}})
	r, _ := c.Collect(context.Background())
	if r.OOB == nil || r.OOB.FelhomSshdPort != 8822 || !r.OOB.Reachable {
		t.Fatalf("oob not carried through: %+v", r.OOB)
	}
}
