package schedule

import (
	"io/fs"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
	"github.com/tidbcloud/metering/pkg/common/config"
	"github.com/tidbcloud/metering/pkg/common/constants"
)

// This Task is for Instance Metering to clean up the cache

type CleanTask struct {
	WatchDir              string        // path to watch
	CleanCacheDelaySecond int64         // delay to clean cache
	Interval              time.Duration // interval to clean cache

}

func NewCleanTask(conf *config.ServiceConfig) *CleanTask {
	return &CleanTask{
		WatchDir:              constants.LocalDataRoot,
		CleanCacheDelaySecond: conf.InstanceMeteringConfig.CleanCacheDelaySecond,
		Interval:              time.Hour * 1,
	}
}

func (t *CleanTask) AsyncTicker() {
	go func() {

		// sleep for a while to wait to clean up the cache
		ticker := time.NewTicker(t.Interval)
		defer ticker.Stop()
		for range ticker.C {
			t.cleanup()
		}
	}()
}

func (t *CleanTask) cleanup() {
	// clean up the cache
	log.Infof("start to clean up cache: %s, cache keep in : %d", t.WatchDir, t.CleanCacheDelaySecond)

	//get the current time
	now := time.Now().Unix()

	// use filepath.WalkDir to scan all files in the directory
	err := filepath.WalkDir(t.WatchDir, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			log.Errorf("path failed: %s, err: %v", path, err)
			return filepath.SkipDir
		}
		if d.IsDir() || path == t.WatchDir {
			return nil
		}

		fileName := d.Name()

		// get timestemp from file name
		parts := strings.Split(fileName, ".")
		if len(parts) == 0 {
			return nil
		}

		timestampStr := parts[0]
		timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
		if err != nil {
			// skip if not vaild timestamp
			return nil
		}

		//diff time
		timeDiff := now - timestamp

		// 检查时间差是否超过阈值
		if timeDiff > t.CleanCacheDelaySecond {
			// delete file
			err := os.Remove(path)
			if err != nil {
				log.Errorf("delete failed: %s, err: %v", path, err)
			} else {
				log.Debugf("deleted file: %s, diff: %v", path, timeDiff)
			}
		}
		return nil
	})

	if err != nil {
		log.Errorf("failed in wallk dir: %v", err)
	}

	log.Infoln("clean up cache done")
}
