package utils

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	baseapi "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/base"
	"github.com/tidbcloud/aisupport/packages/sdk-go/infra/errs"
)

func TestFailWithPlainError(t *testing.T) {
	t.Parallel()

	c, recorder := newTestContext()
	Fail(c, errors.New("plain failure"))

	resp := decodeBaseResponse(t, recorder)
	require.Equal(t, http.StatusInternalServerError, recorder.Code)
	require.Equal(t, http.StatusInternalServerError, resp.ErrCode)
	require.Equal(t, "plain failure", resp.ErrMessage)
}

func TestFailWithAPIError(t *testing.T) {
	t.Parallel()

	c, recorder := newTestContext()
	Fail(c, errs.APIErrorf(http.StatusBadRequest, "bad request"))

	resp := decodeBaseResponse(t, recorder)
	require.Equal(t, http.StatusBadRequest, recorder.Code)
	require.Equal(t, http.StatusBadRequest, resp.ErrCode)
	require.Equal(t, "bad request", resp.ErrMessage)
}

func newTestContext() (*gin.Context, *httptest.ResponseRecorder) {
	gin.SetMode(gin.TestMode)
	recorder := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(recorder)
	return c, recorder
}

func decodeBaseResponse(t *testing.T, recorder *httptest.ResponseRecorder) baseapi.BaseResponse {
	t.Helper()

	var resp baseapi.BaseResponse
	require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &resp))
	return resp
}
