package backup_remove_file

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"sort"
	"strings"
	"time"

	"be.ems/src/framework/cron"
	"be.ems/src/framework/logger"
)

type FileInfo struct {
	Path string
	Info os.FileInfo
}

var NewProcessor = &BackupRemoveFileProcessor{
	count: 0,
}

// BackupRemoveFileProcessor 删除备份文件
type BackupRemoveFileProcessor struct {
	count int // 执行次数
}

func (s *BackupRemoveFileProcessor) Execute(data any) (any, error) {
	s.count++ // 执行次数加一
	options := data.(cron.JobData)
	sysJob := options.SysJob
	logger.Infof("重复:%v 任务ID:%d  执行次数:%d", options.Repeat, sysJob.JobId, s.count)
	// 返回结果，用于记录执行结果
	result := map[string]any{
		"count": s.count,
	}

	// 读取参数值
	var params []struct {
		BackupPath string `json:"backupPath"` // 备份路径 /usr/local/omc/backup/{backupPath}
		StoreDays  int    `json:"storeDays"`  // 保留天数
		StoreNum   int    `json:"storeNum"`   // 保留数量，默认保留7
	}
	err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
	if err != nil {
		return nil, fmt.Errorf("json params err: %v", err)
	}

	for _, item := range params {
		result[item.BackupPath] = ""
		if item.StoreDays < 0 {
			result[item.BackupPath] = "params storeDays less than 0"
			continue
		}
		if item.StoreNum <= 0 {
			item.StoreNum = 7
		}

		// 构建完整备份路径
		filePath := filepath.Join("/usr/local/omc/backup", item.BackupPath)
		if runtime.GOOS == "windows" {
			filePath = fmt.Sprintf("C:%s", filePath)
		}
		// 获取目录下所有备份文件
		files, err := s.files(filePath)
		if err != nil {
			result[item.BackupPath] = "read files err"
			continue
		}
		// 按修改时间排序（从旧到新）
		sort.Slice(files, func(i, j int) bool {
			return files[i].Info.ModTime().Before(files[j].Info.ModTime())
		})

		// 如果文件数量少于保留数量，则不删除
		if len(files) <= item.StoreNum {
			result[item.BackupPath] = fmt.Sprintf("less StoreNum: %d, file number %d", item.StoreNum, len(files))
			continue
		}
		// 计算截止日期
		cutoff := time.Now().AddDate(0, 0, -item.StoreDays)
		// 删除超过保留天数的文件
		deletedErr := []string{}
		for _, file := range files {
			if file.Info.ModTime().Before(cutoff) {
				if err := os.Remove(file.Path); err != nil {
					deletedErr = append(deletedErr, file.Info.Name()) // 记录删除失败的文件名称
				}
			}
		}
		result[item.BackupPath] = strings.Join(deletedErr, ", ")
	}

	// 返回结果，用于记录执行结果
	return result, nil
}

func (s *BackupRemoveFileProcessor) files(dir string) ([]FileInfo, error) {
	var files []FileInfo
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			files = append(files, FileInfo{Path: path, Info: info})
		}
		return nil
	})
	return files, err
}
