package middleware

import (
	"bytes"
	"chonho/config"
	_const "chonho/const"
	"chonho/internal/api-v1/entity"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
)

type bodyLogWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w bodyLogWriter) Write(b []byte) (int, error) {
	w.body.Write(b)
	return w.ResponseWriter.Write(b)
}

func LogResponse(c *gin.Context) {
	var bodyBytes []byte
	if c.Request.Body != nil {
		bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
	}
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

	blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
	c.Writer = blw
	c.Next()

	log.Println(c.Request.Method + " " + c.Request.RequestURI + " " + c.GetHeader("Authorization") + " " + string(bodyBytes) + " " + blw.body.String())
}

func CheckVersion(ctx *gin.Context) {
	if config.Env == "local" {
		return
	}

	// check request token
	//token := ctx.GetHeader("X-App-Request-Token")
	//time := ctx.GetHeader("X-App-Request-Time")
	//checksum := fmt.Sprintf("%x", md5.Sum([]byte(token+"|"+time)))
	//
	//if token == "" || time == "" || checksum != token {
	//	ctx.JSON(http.StatusUnauthorized, entity.ErrorResponse{
	//		Code:    _const.RequestDeny,
	//		Message: "Request Deny",
	//	})
	//	ctx.Abort()
	//	return
	//}

	// check app version
	version := ctx.GetHeader("X-App-Version")
	platform := ctx.GetHeader("X-App-Platform")

	if version == "" || platform == "" {
		ctx.JSON(http.StatusBadRequest, entity.Response{
			Title:   _const.ErrorTitle,
			Code:    _const.StatusBadRequest,
			Message: _const.ClientMessage[_const.StatusBadRequest],
		})
		ctx.Abort()
		return
	}

	versionInt, err := strconv.ParseInt(version, 10, 64)
	if versionInt < config.Version || err != nil {
		ctx.JSON(http.StatusNotFound, entity.Response{
			Title:   _const.ErrorTitle,
			Code:    _const.AppOutOfDate,
			Message: _const.ClientMessage[_const.AppOutOfDate],
		})
		ctx.Abort()
		return
	}
}

func CheckApiVersion(ctx *gin.Context) {
	version := ctx.GetHeader("X-Api-Version")
	if version == "" {
		return
	}
	versionInt, err := strconv.ParseInt(version, 10, 64)
	if versionInt < config.Version || err != nil {
		ctx.JSON(http.StatusNotFound, entity.Response{
			Title:   _const.ErrorTitle,
			Code:    _const.AppOutOfDate,
			Message: _const.ClientMessage[_const.AppOutOfDate],
		})
		ctx.Abort()
		return
	}
}
