package middleware

import (
	"bytes"
	"crawler/model"
	"fmt"
	"io/ioutil"

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

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 GinBodyResponse() gin.HandlerFunc {
	return func(c *gin.Context) {
		var (
			bodyBytes  []byte
			processLog = new(model.ProcessLogModel)
		)

		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()

		/*
			fmt.Printf(
				"Send HTTP response, req uri: %v, method: %v, body: %v, resp code: %v, body: %v",
				c.Request.RequestURI, c.Request.Method, string(bodyBytes), c.Writer.Status(), blw.body.String(),
			)
		*/

		fmt.Printf(
			"Send HTTP response, req uri: %v, method: %v, resp code: %v",
			c.Request.RequestURI, c.Request.Method, c.Writer.Status(),
		)

		processLog.Path = c.Request.RequestURI
		processLog.Code = c.Writer.Status()
		processLog.Method = c.Request.Method
		processLog.RawQuery = c.Request.URL.RawQuery
		processLog.Response = blw.body.String()
		processLog.Request = string(bodyBytes)
		processLog.Save()
	}
}
