package main

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

	"iop/apps/control-plane/internal/wire"
)

func registerFleetHandlers(mux *http.ServeMux, registry *wire.EdgeRegistry, requestStatus edgeStatusRequester, sendCommand edgeCommandSender) {
	registerFleetHandlersWithOptions(mux, registry, requestStatus, sendCommand, fleetOptions{})
}

// registerFleetHandlersWithOptions wires the fleet endpoints to a fleetService
// built from the given options. It exists so tests can inject timeout,
// concurrency, and cache policy without changing the default production wiring.
func registerFleetHandlersWithOptions(mux *http.ServeMux, registry *wire.EdgeRegistry, requestStatus edgeStatusRequester, sendCommand edgeCommandSender, opts fleetOptions) {
	service := newFleetService(registry, requestStatus, sendCommand, opts)
	mux.HandleFunc("/fleet/status", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodGet {
			methodNotAllowed(w, http.MethodGet)
			return
		}
		writeJSON(w, http.StatusOK, service.Status())
	})
	mux.HandleFunc("/fleet/commands", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			methodNotAllowed(w, http.MethodPost)
			return
		}
		var body edgeCommandRequestBody
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
			return
		}
		if body.Operation == "" {
			writeJSON(w, http.StatusBadRequest, map[string]string{"error": "operation is required"})
			return
		}
		if sendCommand == nil {
			writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "command dispatch is not configured"})
			return
		}
		writeJSON(w, http.StatusAccepted, service.Command(body.Operation, body.TargetSelector, body.Parameters))
	})
}
