package controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"path/filepath"
	"skapp/pkg/logger"
	"skapp/pkg/utils/errorx"
	"skapp/pkg/utils/response"
)

type GetPathDto struct {
	// 路径
	Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
}

type GetFileDto struct {
	// 路径
	Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
	// 偏移量
	Offset int64 `form:"offset"`
	// 区块大小
	ChunkSize int64 `form:"chunkSize"`
}

// GetPath
// @Summary      获取文件路径
// @Description  获取文件路径
// @Tags         File
// @Accept       json
// @Produce      json
// @Param		vo query controller.GetPathDto true "获取文件路径"
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /file/path [get]
func GetPath(ctx *gin.Context) {
	dto := &GetPathDto{}
	err := ctx.ShouldBindQuery(dto)
	if err = errorx.ParseError(err); err != nil {
		logger.Log.Errorln(err)
		ctx.JSON(200, err)
	}
	logger.Log.Infof("%+v", dto)

	absPath, _ := filepath.Abs(dto.Path)
	ctx.JSON(200, response.NewResponse(absPath))
}

// GetFile
// @Summary      获取文件
// @Description  获取文件
// @Tags         File
// @Accept       json
// @Produce      octet-stream
// @Param		vo query controller.GetFileDto true "获取文件"
// @Router       /file/ [get]
func GetFile(ctx *gin.Context) {
	dto := &GetFileDto{}
	err := ctx.BindQuery(dto)
	if err != nil {
		ctx.Status(http.StatusInternalServerError)
		logger.Log.Errorln(err)
		return
	}

	offset := dto.Offset
	chunkSize := dto.ChunkSize

	p, _ := filepath.Abs(dto.Path)
	info, err := os.Stat(p)
	if err != nil || info.IsDir() {
		ctx.Status(http.StatusNotFound)
		return
	}

	if offset == 0 && chunkSize == 0 {
		ctx.File(p)
		return
	} else {
		w := ctx.Writer
		ctx.Request.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+chunkSize))
		logger.Log.Debugf("%s", ctx.Request.Header.Get("Range"))
		http.ServeFile(w, ctx.Request, p)
		return
	}
}
