package ginres

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"github.com/pingcap-inc/data-ingestion-tools/pkg/errors"
	"github.com/pingcap-inc/data-ingestion-tools/pkg/log"
)

type Response struct {
	// Code defines the business error code.
	Code int `json:"code"`

	// Message contains the detail of this message.
	// This message is suitable to be exposed to external
	Message string `json:"message"`

	// Reference returns the reference document which maybe useful to solve this error.
	Reference string `json:"reference,omitempty"`

	// Maybe can fill partial data
	Data interface{} `json:"data"`
}

// WriteResponse write an error or the response data into http response body.
// It use errors.ParseCoder to parse any error into errors.Coder
// errors.Coder contains error code, user-safe error message and http status code.
func WriteResponse(c *gin.Context, err error, data interface{}) {
	if err != nil {
		log.Errorf("%#+v", err)
		coder := errors.ParseCoder(err)
		c.JSON(coder.HTTPStatus(), Response{
			Code:      coder.Code(),
			Message:   coder.String(),
			Reference: coder.Reference(),
			Data:      data,
		})

		return
	}

	c.JSON(http.StatusOK, &Response{
		Code:    0,
		Message: "",
		Data:    data,
	})
}

func WriteRawResponse(c *gin.Context, err error, res interface{}) {
	if err != nil {
		log.Errorf("%#+v", err)
		c.JSON(http.StatusInternalServerError, err)

		return
	}

	c.JSON(http.StatusOK, res)
}
