package com.bsmlab.dfx.agent.task.status;

import com.bsmlab.dfx.agent.config.AgentConfigReader;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ScheduledFuture;

@Slf4j
@RequiredArgsConstructor
@Service
public class FileCleanerSchedulerService {
    private final ThreadPoolTaskScheduler fileCleanerThreadPoolTaskScheduler;
    private final AgentConfigReader agentConfigReader;
    private ScheduledFuture<?> scheduledFuture;

    // StartupRunner 로 부터 실행됨
    public void launch() {
        log.debug("FileCleanerSchedulerService launch");
        this.scheduledFuture = fileCleanerThreadPoolTaskScheduler.scheduleWithFixedDelay(this::run, Duration.ofHours(1));
    }

    public void run() {
        String processedMessageStorageRoot = agentConfigReader.getAgentConfigDto().getDropBoxConfig().getProcessedMessageStorageRoot();
        File processedMessageStorage = new File(processedMessageStorageRoot);
        String sentMessageStorageRoot = agentConfigReader.getAgentConfigDto().getDropBoxConfig().getSentMessageStorageRoot();
        File sentMessageStorage = new File(sentMessageStorageRoot);
        List<File> allDirectoryList = new ArrayList<>();
        this.findDirectory(processedMessageStorage, allDirectoryList);
        this.findDirectory(sentMessageStorage, allDirectoryList);
        Calendar calendar = Calendar.getInstance();
        int toDateCount = agentConfigReader.getAgentConfigDto().getDropBoxConfig().getRetentionDaysOfProcessedMessage() * -1;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        for(int i = 0; i < toDateCount; i++) {
            calendar.roll(Calendar.DATE, (i * -1));
            Date currentDate = calendar.getTime();
            String retentionDirectoryString1 = processedMessageStorageRoot + "/" + dateFormat.format(currentDate);
            String retentionDirectoryString2 = sentMessageStorageRoot + "/" + dateFormat.format(currentDate);
            Iterator<File> iterator = allDirectoryList.iterator();
            while(iterator.hasNext()) {
                File file = iterator.next();
                if(file.getAbsolutePath().contains(retentionDirectoryString1) || file.getAbsolutePath().contains(retentionDirectoryString2)) {
                    allDirectoryList.remove(file);
                }
            }
        }
        for(File file : allDirectoryList) {
            if(file.exists()) {
                this.deleteDirectory(file);
            }
        }
    }

    private void findDirectory(File parent, List<File> fileList) {
        File[] files = parent.listFiles();
        for(File file : files) {
            if(!".".equals(file.getName()) && !"..".equals(file.getName()) && file.isDirectory()) {
                fileList.add(file);
                this.findDirectory(file, fileList);
            }
        }
    }

    private void deleteDirectory(File targetDirectory) {
        File[] files = targetDirectory.listFiles();
        if(files == null) {
            targetDirectory.delete();
        }
        else {
            for(File file : files) {
                if(file.isFile()) {
                    file.delete();
                }
                else if(file.isDirectory() && !".".equals(file.getName()) && !"..".equals(file.getName())) {
                    this.deleteDirectory(file);
                }
            }
        }
    }

}
