package ru.yandex.webmaster3.worker.notifications;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.notifications.SearchBaseNotificationInfo;
import ru.yandex.webmaster3.storage.notifications.dao.NotificationCHTablesManager;
import ru.yandex.webmaster3.storage.notifications.dao.NotificationTableInfo;
import ru.yandex.webmaster3.storage.notifications.dao.SearchBaseNotificationsYDao;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * @author avhaliullin
 */
@Setter
public class CleanupNotificationsTask extends PeriodicTask<PeriodicTaskState> {
    private static final Logger log = LoggerFactory.getLogger(CleanupNotificationsTask.class);

    private NotificationCHTablesManager notificationCHTablesManager;
    private SearchBaseNotificationsYDao searchBaseNotificationsYDao;

    @Override
    public Result run(UUID runId) throws Exception {
        List<NotificationTableInfo> tables = notificationCHTablesManager.listNotificationTables();
        Map<UUID, List<NotificationTableInfo>> notificationId2Tables =
                tables.stream().collect(Collectors.groupingBy(NotificationTableInfo::getNotificationId));
        int totallyDeleted = 0;
        for (Map.Entry<UUID, List<NotificationTableInfo>> entry : notificationId2Tables.entrySet()) {
            UUID keepRecList;
            SearchBaseNotificationInfo searchBaseNotificationInfo =
                    searchBaseNotificationsYDao.getNotificationInfo(entry.getKey());
            if (searchBaseNotificationInfo != null) {
                keepRecList = searchBaseNotificationInfo.getRecListId();
            } else {
                keepRecList = null;
            }
            List<NotificationTableInfo> toDelete = new ArrayList<>();
            if (keepRecList == null) {
                toDelete = entry.getValue();
            } else {
                for (NotificationTableInfo tableInfo : entry.getValue()) {
                    if (!Objects.equals(tableInfo.getListId(), keepRecList)) {
                        toDelete.add(tableInfo);
                    }
                }
            }

            totallyDeleted += toDelete.size();
            notificationCHTablesManager.deleteTables(toDelete);
        }
        log.info("Deleted {} tables", totallyDeleted);
        return new Result(TaskResult.SUCCESS);
    }

    @Override
    public PeriodicTaskType getType() {
        return PeriodicTaskType.CLEANUP_NOTIFICATIONS;
    }

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.startByCron("0 0 11 * * *");
    }
}
