package controller

import (
	"fmt"
	"path/filepath"
	"strings"

	"be.ems/src/framework/i18n"
	"be.ems/src/framework/utils/ctx"
	"be.ems/src/framework/utils/file"
	"be.ems/src/framework/utils/ssh"
	"be.ems/src/framework/vo/result"
	neService "be.ems/src/modules/network_element/service"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

// 实例化控制层 NeActionController 结构体
var NewNeAction = &NeActionController{
	neInfoService: neService.NewNeInfoImpl,
}

// 网元处理请求
//
// PATH /action
type NeActionController struct {
	// 网元信息服务
	neInfoService neService.INeInfo
}

// 发送文件到网元端
//
// POST /pushFile
func (s *NeActionController) PushFile(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	var body struct {
		NeType     string `json:"neType" binding:"required"`
		NeID       string `json:"neId" binding:"required"`
		UploadPath string `json:"uploadPath" binding:"required"`
	}
	if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	// 查询网元获取IP
	neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeID)
	if neInfo.NeId != body.NeID || neInfo.IP == "" {
		c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 本地文件
	localPath := file.ParseUploadFilePath(body.UploadPath)
	nePath := "/tmp" //config.Get("mml.upload").(string)
	// 复制到远程
	err := ssh.FileSCPLocalToNe(neInfo.IP, localPath, nePath)
	if err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}

	// 网元端文件路径
	fileName := localPath[strings.LastIndex(localPath, "/")+1:]
	neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
	c.JSON(200, result.OkData(filepath.ToSlash(neFilePath)))
}

// 获取文件从网元到本地
//
// GET /pullFile
func (s *NeActionController) PullFile(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	var querys struct {
		NeType   string `form:"neType" binding:"required"`
		NeID     string `form:"neId" binding:"required"`
		Path     string `form:"path" binding:"required"`
		FileName string `form:"fileName" binding:"required"`
	}
	if err := c.ShouldBindQuery(&querys); err != nil {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	// 查询网元获取IP
	neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
	if neInfo.NeId != querys.NeID || neInfo.IP == "" {
		c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	nePath := fmt.Sprintf("%s/%s", querys.Path, querys.FileName)
	localPath := fmt.Sprintf("/tmp/omc/pullFile/%s", querys.FileName)
	err := ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath)
	if err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}
	c.FileAttachment(localPath, querys.FileName)
}

// 网元端文件列表
//
// GET /files
func (s *NeActionController) Files(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	var querys struct {
		NeType   string `form:"neType" binding:"required"`
		NeID     string `form:"neId" binding:"required"`
		Path     string `form:"path"  binding:"required"`
		PageNum  int64  `form:"pageNum"  binding:"required"`
		PageSize int64  `form:"pageSize"  binding:"required"`
		Search   string `form:"search"`
	}
	if err := c.ShouldBindQuery(&querys); err != nil {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	// 查询网元获取IP
	neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
	if neInfo.NeId != querys.NeID || neInfo.IP == "" {
		c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	totalSize, rows, err := ssh.FileList(querys.Path, neInfo.IP, querys.Search)
	if err != nil {
		c.JSON(200, result.Ok(map[string]any{
			"path":      querys.Path,
			"totalSize": totalSize,
			"total":     len(rows),
			"rows":      []ssh.FileListRow{},
		}))
		return
	}

	// 对数组进行切片分页
	lenNum := int64(len(rows))
	start := (querys.PageNum - 1) * querys.PageSize
	end := start + querys.PageSize
	var splitRows []ssh.FileListRow
	if start >= lenNum {
		splitRows = []ssh.FileListRow{}
	} else if end >= lenNum {
		splitRows = rows[start:]
	} else {
		splitRows = rows[start:end]
	}

	c.JSON(200, result.Ok(map[string]any{
		"path":      querys.Path,
		"totalSize": totalSize,
		"total":     lenNum,
		"rows":      splitRows,
	}))
}
