package healthcheck

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

// Response 是 gateway HTTP health endpoint 的稳定 JSON 契约。
type Response struct {
	Status     string  `json:"status"`
	Service    string  `json:"service"`
	NodeID     string  `json:"node_id"`
	TimeUnixMS int64   `json:"time_unix_ms"`
	Checks     []Check `json:"checks,omitempty"`
}

// HTTPHandler 暴露 /healthz/live 和 /healthz/ready 两个只读入口。
type HTTPHandler struct {
	state *State
}

// NewHTTPHandler 创建 gateway health HTTP handler。
func NewHTTPHandler(state *State) *HTTPHandler {
	return &HTTPHandler{state: state}
}

// Live 返回进程自身是否仍可运行。
func (h *HTTPHandler) Live(writer http.ResponseWriter, request *http.Request) {
	checks := h.state.Live()
	statusCode := http.StatusOK
	if !Healthy(checks) {
		statusCode = http.StatusInternalServerError
	}

	h.write(writer, statusCode, checks)
}

// Ready 返回当前 gateway 实例是否可以接新 HTTP 请求。
func (h *HTTPHandler) Ready(writer http.ResponseWriter, request *http.Request) {
	checks := h.state.Ready(request.Context())
	statusCode := http.StatusOK
	if !Healthy(checks) {
		statusCode = http.StatusServiceUnavailable
	}

	h.write(writer, statusCode, checks)
}

func (h *HTTPHandler) write(writer http.ResponseWriter, statusCode int, checks []Check) {
	status := componentStatus
	if !Healthy(checks) {
		status = failStatus
	}

	response := Response{
		Status:     status,
		Service:    h.state.ServiceName(),
		NodeID:     h.state.NodeID(),
		TimeUnixMS: time.Now().UnixMilli(),
	}
	if status != componentStatus {
		response.Checks = checks
	}

	writer.Header().Set("Content-Type", "application/json")
	writer.WriteHeader(statusCode)
	_ = json.NewEncoder(writer).Encode(response)
}
