package ru.yandex.webmaster3.worker.ytimport;

import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.collect.Sets;
import lombok.Setter;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.storage.clickhouse.system.dao.ClickhouseSystemPartsCHDao;
import ru.yandex.webmaster3.storage.clickhouse.system.dao.ClickhouseSystemTablesCHDao;
import ru.yandex.webmaster3.storage.searchquery.SearchQueriesConstants;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseException;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseQueryContext;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseServer;
import ru.yandex.webmaster3.worker.PeriodicTask;

import static ru.yandex.webmaster3.storage.searchquery.SearchQueriesConstants.TEMP_PREFIX;

public abstract class AbstractSwitchDatesTask<T extends PeriodicTaskState> extends PeriodicTask<T> {

    private static final Logger log = LoggerFactory.getLogger(AbstractSwitchDatesTask.class);

    @Setter
    protected ClickhouseServer clickhouseServer;
    @Setter
    protected ClickhouseSystemTablesCHDao clickhouseSystemTablesCHDao;
    @Setter
    protected ClickhouseSystemPartsCHDao clickhouseSystemPartsCHDao;

    protected void renameTables(LocalDate dateTo, String db, String prefix, Pattern pattern) throws ClickhouseException {
        renameTables(dateTo, db, prefix, pattern, Integer.MAX_VALUE);
    }

    protected void renameTables(LocalDate dateTo, String db, String prefix, Pattern pattern, int maxShard)
            throws ClickhouseException {
        // ищем все подходящие временные таблички
        Set<String> tableNames = clickhouseSystemTablesCHDao.getTableNamesForPrefix(db, prefix, maxShard, true);
        // оставляем только те, у которых дата в названии меньше или равна необходимой
        boolean empty = true;
        StringBuilder query = new StringBuilder("RENAME TABLE ");
        for (String tableName : tableNames) {
            Matcher matcher = pattern.matcher(tableName);
            if (!matcher.matches()) {
                log.warn("Found strange table {} in {}", tableName, db);
                continue;
            }
            LocalDate tableDate = SearchQueriesConstants.IN_TABLE_NAME_DATE_FORMATTER.parseLocalDate(matcher.group(1));
            if (!tableDate.isAfter(dateTo)) {
                if (empty) {
                    empty = false;
                } else {
                    query.append(", ");
                }
                // проверим, что все таблицы непустые
                clickhouseSystemPartsCHDao.checkTablesNotEmpty(db, Sets.newHashSet(tableName), maxShard);
                // отрезаем префикс tmp
                query.append(db).append(".").append(tableName).append(" TO ");
                query.append(db).append(".");
                query.append(tableName.substring(TEMP_PREFIX.length()));
            }
        }
        log.info("Removing temp prefix from tables: {}", query.toString());
        // переименовываем все
        if (!empty) {
            clickhouseServer.executeOnAllHosts(ClickhouseQueryContext.useDefaults(), query.toString(), maxShard);
        }
    }
}
