package wrapper

import (
	"common/net/http/http_resp"
	"common/proto/ss/ss_common"
	"context"
	"encoding/json"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
)

// ErrorHandler 将 gRPC 错误转为统一 JSON 格式
func ErrorHandler(_ context.Context, _ *runtime.ServeMux, _ runtime.Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
	st, ok := status.FromError(err)
	if !ok {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusInternalServerError)
		_ = json.NewEncoder(w).Encode(http_resp.Error(http_resp.Failed))
		return
	}

	code, msg := 0, ""
	for _, detail := range st.Details() {
		if errorInfo, ok := detail.(*ss_common.ErrorInfo); ok {
			code = int(errorInfo.Code)
			msg = errorInfo.Msg
			break
		}
	}
	if code == 0 {
		code = http_resp.Failed.Code()
		msg = http_resp.Failed.Error()
	}
	if st.Code() == codes.Unknown ||
		st.Code() == codes.Unimplemented ||
		st.Code() == codes.NotFound {
		msg = st.Message()
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(grpcCodeToHTTPCode(st.Code()))
	_ = json.NewEncoder(w).Encode(http_resp.Error(http_resp.NewCode(code, msg)))
}

// 这里定义 Internal 属于业务错误，其他的属于 500 报错
func grpcCodeToHTTPCode(c codes.Code) int {
	switch c {
	case codes.OK, codes.Unknown:
		return http.StatusOK
	case codes.Unimplemented, codes.NotFound:
		return http.StatusNotFound
	default:
		return http.StatusInternalServerError
	}
}
