package request

import (
	"fmt"
	"net/http"
	"runtime"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

type Checker interface {
	Check() error
}

func ParseParamFail(ctx *gin.Context, r interface{}, fs ...func() error) bool {
	if r != nil {
		if Fail(ctx, http.StatusBadRequest, ctx.ShouldBind(r)) {
			return true
		}

		if checker, ok := r.(Checker); ok {
			return Fail(ctx, http.StatusBadRequest, checker.Check())
		}
	}

	for _, f := range fs {
		if Fail(ctx, http.StatusBadRequest, f()) {
			return true
		}
	}

	return false
}

func Fail(ctx *gin.Context, status int, err error) bool {
	if err == nil {
		return false
	}

	ctx.JSON(status, HTTPError{Msg: err.Error()})

	if status == http.StatusInternalServerError {
		_, file, line, _ := runtime.Caller(1)
		logrus.WithField("err", err).Errorf("file:%s line:%d", file, line)
	}

	return true
}

func Success(ctx *gin.Context, data interface{}) {
	if data == nil {
		ctx.Status(http.StatusNoContent)
		return
	}

	switch ctx.Request.Method {
	case http.MethodGet, http.MethodHead, http.MethodOptions:
		ctx.JSON(http.StatusOK, data)
	case http.MethodPost, http.MethodPut, http.MethodPatch:
		ctx.JSON(http.StatusCreated, data)
	default:
		ctx.JSON(http.StatusBadRequest, HTTPError{Msg: fmt.Sprintf("unsupported request method %s", ctx.Request.Method)})
	}
}