package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
	"net/http"
	"server-go/router"
	"server-go/service"
)

func myValidate(fl validator.FieldLevel) bool {
	fmt.Println(fl.Field().Interface().(int))
	return true
}

func main() {

	// init the db connection
	service.InitDB()

	// all the route
	engine := router.Routers()

	// Get方法
	engine.GET("/ping", func(c *gin.Context) {

		statusOK := http.StatusOK
		c.JSON(
			statusOK,
			gin.H{})
	})

	// Post方法，接收request body的形式
	engine.POST("/jsonPost", func(c *gin.Context) {

		// 自定义 请求规则验证器
		if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
			v.RegisterValidation("myValidation", myValidate)
		}

		var p string
		err := c.ShouldBindJSON(&p)
		if err != nil {
			return
		}
	})

	// 上传文件的操作 前端上传文件使用的是form-data的形式
	// 单个文件上传
	engine.POST("/upload", func(c *gin.Context) {
		file, err := c.FormFile("file") // 获取上传的文件
		if err != nil {
			c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
			return
		}
		// 如果有其他的表单信息
		c.DefaultPostForm("name", "default-file-name")

		// 打印文件信息
		fmt.Printf("File Name: %s\n", file.Filename)
		fmt.Printf("File Size: %d bytes\n", file.Size)
		fmt.Printf("MIME ExecutionType: %s\n", file.Header.Get("Content-ExecutionType"))

		// 保存文件到本地
		err = c.SaveUploadedFile(file, "./"+file.Filename)
		if err != nil {
			c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
			return
		}

		c.String(200, fmt.Sprintf("%s uploaded successfully!", file.Filename))
	})

	// 多个文件上传
	engine.POST("/multi-upload", func(c *gin.Context) {
		form, err := c.MultipartForm() // 获取多个文件上传表单
		if err != nil {
			c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
			return
		}

		// 遍历所有上传的文件
		files := form.File["files"]
		for _, file := range files {
			// 打印文件信息
			fmt.Printf("File Name: %s\n", file.Filename)
			fmt.Printf("File Size: %d bytes\n", file.Size)
			fmt.Printf("MIME ExecutionType: %s\n", file.Header.Get("Content-ExecutionType"))

			// 保存文件到本地
			err = c.SaveUploadedFile(file, "./"+file.Filename)
			if err != nil {
				c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
				return
			}
		}

		c.String(200, fmt.Sprintf("%d files uploaded successfully!", len(files)))
	})

	// 返回静态文件
	engine.GET("/file", func(c *gin.Context) {
		c.File("./example.txt") // 返回指定路径的文件
	})

	// 返回动态生成的文件
	engine.GET("/download", func(c *gin.Context) {
		content := "Hello, world!"
		fileName := "example.txt"

		// 设置响应头，使浏览器可以下载文件
		c.Header("Content-Disposition", "attachment; filename="+fileName)
		c.Header("Content-ExecutionType", "application/octet-stream")
		c.Header("Content-Transfer-Encoding", "binary")
		c.Header("Cache-Control", "no-cache")

		// 将内容写入响应体中
		c.String(http.StatusOK, content)
	})

	engine.Run(":9090")

}
