// 中间件模块-参数加解密
// 秒寻科技
// 2024-02-18
// 周涛

package endecrypt

import (
	"bytes"
	"encoding/json"
	"io"
	"ipsomc/util"
	"net/http"

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

// 解密请求参数
func DecryptReqParam() func(c *gin.Context) {
	return func(c *gin.Context) {
		//请求中有路由参数
		urlParam := c.Request.URL.RawQuery //请求中的路由参数
		if urlParam != "" {
			//参数解密
			res, err := util.DecryptAes(urlParam)
			if err != nil {
				c.String(http.StatusBadRequest, err.Error())
				c.Abort()
				return
			}

			c.Request.URL.RawQuery = res //将解密后的路由参数回写到请求中
		}

		//body中有参数
		bodyData, err := io.ReadAll(c.Request.Body)
		if err != nil {
			c.String(http.StatusBadRequest, err.Error())
			c.Abort()
			return
		}
		defer c.Request.Body.Close()

		if len(bodyData) == 0 {
			c.Next()
			return
		}

		plainBuf, err := util.DecryptAes(string(bodyData))
		if err != nil {
			c.String(http.StatusBadRequest, err.Error())
			c.Abort()
			return
		}

		r := bytes.NewBuffer([]byte(plainBuf))
		rd := io.NopCloser(r)
		c.Request.Body = rd //将解密参数回写到请求中
	}
}

// 移动端解密请求参数
func MobileDecryptReqParam() func(c *gin.Context) {
	return func(c *gin.Context) {
		////解密请求头
		authorizationParam := c.Request.Header.Get("Authorization")
		if authorizationParam != "" {
			type headers struct {
				Rnd   string `json:"rnd"`
				Token string `json:"token"`
			}
			var myHead headers

			resp, err := util.DecryptAes(authorizationParam)
			if err != nil {
				c.String(http.StatusBadRequest, err.Error())
				c.Abort()
				return
			}

			if err := json.Unmarshal([]byte(resp), &myHead); err != nil {
				c.String(http.StatusBadRequest, err.Error())
				c.Abort()
				return
			}

			c.Request.Header.Set("Authorization", myHead.Token)
		}

		////解密路由参数，就是get请求的参数
		urlParam := c.Request.URL.RawQuery //请求中的路由参数
		if urlParam != "" {
			//参数解密
			res, err := util.DecryptAes(urlParam)
			if err != nil {
				c.String(http.StatusBadRequest, err.Error())
				c.Abort()
				return
			}

			c.Request.URL.RawQuery = res //将解密后的路由参数回写到请求中
		}

		////解密body参数，就是post请求的参数
		bodyData, err := io.ReadAll(c.Request.Body)
		if err != nil {
			c.String(http.StatusBadRequest, err.Error())
			c.Abort()
			return
		}
		defer c.Request.Body.Close()

		if len(bodyData) == 0 {
			c.Next()
			return
		}

		plainBuf, err := util.DecryptAes(string(bodyData))
		if err != nil {
			c.String(http.StatusBadRequest, err.Error())
			c.Abort()
			return
		}

		r := bytes.NewBuffer([]byte(plainBuf))
		rd := io.NopCloser(r)
		c.Request.Body = rd //将解密参数回写到请求中
	}
}
