package utils

import (
	"bytes"
	"io"
	"net/http"

	"github.com/gin-gonic/gin"
	baseapi "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/base"
	"github.com/tidbcloud/aisupport/packages/sdk-go/infra/errs"
	"go.opentelemetry.io/otel/trace"
)

// FetchBody fetches the request body and puts it back to the request.
func FetchBody(c *gin.Context) ([]byte, error) {
	body, err := c.GetRawData()
	c.Request.Body.Close()
	if err != nil {
		return nil, err
	}

	c.Request.Body = io.NopCloser(bytes.NewReader(body))
	return body, nil
}

// Fail sets the errcode and errmessage to the response and aborts the request.
func Fail(c *gin.Context, err error) {
	aerr := errs.APIErrorWrap(err)
	resp := &baseapi.BaseResponse{
		ErrCode:    aerr.ErrCode(),
		ErrMessage: aerr.ErrMessage(),
		TraceID:    trace.SpanContextFromContext(c).TraceID().String(),
	}
	c.AbortWithStatusJSON(aerr.ErrCode(), resp)
	c.Error(err)
}

// Success sets the errcode to 0 and returns the response.
func Success(c *gin.Context, resp any) {
	if resp == nil {
		resp = &baseapi.BaseResponse{
			ErrCode:    http.StatusOK,
			ErrMessage: "",
			TraceID:    trace.SpanContextFromContext(c).TraceID().String(),
		}
	} else {
		baseapi.SetBaseResp(resp, http.StatusOK, "", trace.SpanContextFromContext(c).TraceID().String())
	}
	c.JSON(http.StatusOK, resp)
}
