package handlers import ( "net/http" "sort" "time" "sneak.berlin/go/dnswatcher/internal/state" ) // nameserverRecordResponse represents one nameserver's records // in the API response. type nameserverRecordResponse struct { Nameserver string `json:"nameserver"` Records map[string][]string `json:"records"` Status string `json:"status"` Error string `json:"error,omitempty"` LastChecked string `json:"lastChecked,omitempty"` } // hostnameResponse represents a single hostname in the API response. type hostnameResponse struct { Hostname string `json:"hostname"` Nameservers []nameserverRecordResponse `json:"nameservers,omitempty"` LastChecked string `json:"lastChecked,omitempty"` Status string `json:"status"` } // hostnamesResponse is the top-level response for // GET /api/v1/hostnames. type hostnamesResponse struct { Hostnames []hostnameResponse `json:"hostnames"` } // HandleHostnames returns the configured hostnames and their status. func (h *Handlers) HandleHostnames() http.HandlerFunc { return func( writer http.ResponseWriter, request *http.Request, ) { configured := h.config.Hostnames snapshot := h.state.GetSnapshot() hostnames := make( []hostnameResponse, 0, len(configured), ) for _, hostname := range configured { hr := hostnameResponse{ Hostname: hostname, Status: "pending", } hs, ok := snapshot.Hostnames[hostname] if ok { hr.Status = "ok" if !hs.LastChecked.IsZero() { hr.LastChecked = hs.LastChecked. Format(time.RFC3339) } hr.Nameservers = buildNameserverRecords( hs, ) } hostnames = append(hostnames, hr) } h.respondJSON( writer, request, &hostnamesResponse{Hostnames: hostnames}, http.StatusOK, ) } } // buildNameserverRecords converts the per-nameserver state map // into a sorted slice for deterministic JSON output. func buildNameserverRecords( hs *state.HostnameState, ) []nameserverRecordResponse { if hs.RecordsByNameserver == nil { return nil } nsNames := make( []string, 0, len(hs.RecordsByNameserver), ) for ns := range hs.RecordsByNameserver { nsNames = append(nsNames, ns) } sort.Strings(nsNames) records := make( []nameserverRecordResponse, 0, len(nsNames), ) for _, ns := range nsNames { nsr := hs.RecordsByNameserver[ns] entry := nameserverRecordResponse{ Nameserver: ns, Records: nsr.Records, Status: nsr.Status, Error: nsr.Error, } if !nsr.LastChecked.IsZero() { entry.LastChecked = nsr.LastChecked. Format(time.RFC3339) } records = append(records, entry) } return records }