package api

import (
	"encoding/json"
	"net/http"
	"testing"

	"gitea.dooplex.hu/admin/felhom-hub/internal/store"
)

// Part D over the wire: the report ACK WITHHOLDS the controller floor for a box whose agent is below
// the golden's MinAgent, and serves it once the agent qualifies. Companion red-proof: revert the
// report handler to the ungated EffectiveMinControllerVersion → the held case leaks the floor.
func TestReportACK_ManagedFloorHold(t *testing.T) {
	h, st, _ := newTestHandler(t)
	st.SetDefaultMinControllerVersion("0.113.0")                                                  // controller floor
	_ = st.SetArtifactManifest(store.ArtifactManifest{GoldenVersion: "0.113.0", MinAgent: "0.81.0"}) // coupled golden
	if err := st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: "c", RetrievalPassword: "pw", APIKey: "k", ConfigJSON: "{}"}); err != nil {
		t.Fatal(err)
	}
	if err := st.UpsertHost(&store.Host{HostID: "hc", CustomerID: "c", APIKey: "hc-key"}); err != nil {
		t.Fatal(err)
	}

	ackFloor := func() (interface{}, bool) {
		rr := do(h, http.MethodPost, "/report", globalKey, `{"customer_id":"c"}`)
		if rr.Code != http.StatusOK {
			t.Fatalf("report status = %d", rr.Code)
		}
		var ack map[string]interface{}
		_ = json.Unmarshal(rr.Body.Bytes(), &ack)
		v, ok := ack["min_controller_version"]
		return v, ok
	}

	// Agent below MinAgent → the floor is HELD (ACK omits it).
	if err := st.SaveHostReport("hc", "c", []byte(`{}`), store.HostReportDenorm{AgentVersion: "0.79.0"}); err != nil {
		t.Fatal(err)
	}
	if v, ok := ackFloor(); ok {
		t.Errorf("held box: ACK must OMIT the floor, got %v", v)
	}

	// Agent updates to ≥ MinAgent → the floor is now served.
	if err := st.SaveHostReport("hc", "c", []byte(`{}`), store.HostReportDenorm{AgentVersion: "0.82.0"}); err != nil {
		t.Fatal(err)
	}
	if v, ok := ackFloor(); !ok || v != "0.113.0" {
		t.Errorf("qualified box: ACK must serve the floor 0.113.0, got %v (present=%v)", v, ok)
	}
}
