package com.screenshot.scheduler;
import com.screenshot.config.AppConfig;
import com.screenshot.service.UploadService;
import com.screenshot.service.ZipService;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.concurrent.*;
/**
* Планировщик ежедневной отправки скриншотов на сервер
*/
public class UploadScheduler {
private final ScheduledExecutorService scheduler;
private final ZipService zipService;
private final UploadService uploadService;
private final AppConfig config;
private ScheduledFuture<?> currentTask;
private volatile boolean running = false;
public UploadScheduler(AppConfig config) {
this.scheduler = Executors.newScheduledThreadPool(1);
this.zipService = new ZipService();
this.uploadService = new UploadService();
this.config = config;
}
/**
* Запустить планировщик
*/
public void start() {
if (!config.isUploadEnabled()) {
System.out.println("Автоматическая отправка отключена");
return;
}
if (running) {
System.out.println("Планировщик отправки уже запущен");
return;
}
running = true;
scheduleNextUpload();
System.out.println("Планировщик отправки запущен. Время отправки: " +
config.getUploadScheduleTime());
}
/**
* Запланировать следующую отправку
*/
private void scheduleNextUpload() {
if (!running) return;
LocalTime uploadTime = config.getUploadScheduleTime();
LocalDateTime now = LocalDateTime.now();
LocalDateTime nextRun = now.toLocalDate().atTime(uploadTime);
// Если время сегодня уже прошло, планируем на завтра
if (now.isAfter(nextRun)) {
nextRun = nextRun.plusDays(1);
}
long delayMillis = Duration.between(now, nextRun).toMillis();
System.out.println("Следующая отправка запланирована на: " + nextRun);
currentTask = scheduler.schedule(() -> {
performUpload();
scheduleNextUpload(); // Планируем следующую
}, delayMillis, TimeUnit.MILLISECONDS);
}
/**
* Выполнить отправку
*/
public void performUpload() {
System.out.println("\n========== НАЧАЛО ОТПРАВКИ ==========");
System.out.println("Время: " + LocalDateTime.now());
Path sourcePath = Path.of(config.getSavePath());
Path tempDir = sourcePath.resolve(".temp_upload");
try {
// Проверяем доступность сервера
String serverUrl = config.getUploadServerUrl();
System.out.println("Проверка сервера: " + serverUrl);
if (!uploadService.isServerAvailable(serverUrl)) {
System.err.println("Сервер недоступен!");
return;
}
System.out.println("Сервер доступен");
// Создаём ZIP архивы
System.out.println("Создание архивов...");
List<Path> archives = zipService.createZipArchives(
sourcePath,
tempDir,
config.getMaxZipSizeBytes()
);
if (archives.isEmpty()) {
System.out.println("Нет файлов для отправки");
return;
}
System.out.println("Создано архивов: " + archives.size());
// Отправляем архивы поочерёдно
int successCount = 0;
int failCount = 0;
for (int i = 0; i < archives.size(); i++) {
Path archive = archives.get(i);
System.out.println("\nОтправка " + (i + 1) + "/" + archives.size() +
": " + archive.getFileName());
UploadService.UploadResult result = uploadService.uploadWithRetry(
archive,
serverUrl,
config.getUploadRetryCount(),
config.getUploadRetryDelaySeconds()
);
if (result.success()) {
successCount++;
} else {
failCount++;
System.err.println("Не удалось отправить: " + archive.getFileName());
}
}
// Итоги
System.out.println("\n----- ИТОГИ -----");
System.out.println("Успешно: " + successCount);
System.out.println("Ошибок: " + failCount);
// Удаляем исходные файлы если настроено
if (failCount == 0 && config.isDeleteAfterUpload()) {
System.out.println("Удаление исходных файлов...");
zipService.deleteSourceFiles(sourcePath);
}
// Удаляем временные архивы
zipService.deleteArchives(archives);
// Удаляем временную директорию
Files.deleteIfExists(tempDir);
} catch (IOException e) {
System.err.println("Ошибка отправки: " + e.getMessage());
e.printStackTrace();
}
System.out.println("========== КОНЕЦ ОТПРАВКИ ==========\n");
}
/**
* Остановить планировщик
*/
public void stop() {
running = false;
if (currentTask != null) {
currentTask.cancel(false);
}
System.out.println("Планировщик отправки остановлен");
}
/**
* Перезапустить с новыми настройками
*/
public void restart() {
stop();
start();
}
/**
* Завершить работу
*/
public void shutdown() {
stop();
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
}
public boolean isRunning() {
return running;
}
}