package ru.yandex.webmaster3.monitoring.indexing2;

import java.util.ArrayList;
import java.util.List;

import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;

import ru.yandex.webmaster3.core.solomon.HandleCommonMetricsService;
import ru.yandex.webmaster3.core.solomon.Indicators;
import ru.yandex.webmaster3.core.solomon.SolomonSensor;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.storage.indexing2.internal.dao.IndexingHistoryTablesYDao;
import ru.yandex.webmaster3.storage.indexing2.internal.dao.IndexingSamplesTablesYDao;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryImportType;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryTableImport;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryTableImportState;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingSamplesImportType;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingSamplesTableInfo;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingSamplesTableState;

/**
 * Сервис мониторинга статистики обхода (WMC-3991)
 * Created by Oleg Bazdyrev on 11/05/2017.
 */
public class IndexingTablesMonitoringService {
    private static final Logger log = LoggerFactory.getLogger(IndexingTablesMonitoringService.class);
    private static final String INDEXING_SECTION_LABEL_VALUE = "indexing";
    private static final String URL_SAMPLES_DATA_TYPE = "url_samples";
    private static final String EVENT_SAMPLES_DATA_TYPE = "event_samples";
    private static final String URL_HISTORY_DATA_TYPE = "url_history";
    private static final String EVENT_HISTORY_DATA_TYPE = "event_history";
    private static final int AVERAGE_SENSORS_SIZE = 600; // TODO подумать

    @Setter
    private HandleCommonMetricsService handleCommonMetricsService;
    @Setter
    private IndexingSamplesTablesYDao indexingSamplesTablesYDao;
    @Setter
    private IndexingHistoryTablesYDao indexingHistoryTablesYDao;
    @Setter
    private boolean enabled;
    @Setter
    private long refreshIntervalSeconds;

    @Scheduled(cron = "${webmaster3.monitoring.solomon.indexing.refresh-cron}")
    private void push() throws Exception {
        if (!enabled) {
            return;
        }
        List<SolomonSensor> sensors = new ArrayList<>();
        sensors.add(createSamplesSensor(IndexingSamplesImportType.URL_SAMPLES, URL_SAMPLES_DATA_TYPE));
        sensors.add(createSamplesSensor(IndexingSamplesImportType.EVENT_SAMPLES, EVENT_SAMPLES_DATA_TYPE));

        sensors.add(createHistorySensor(IndexingHistoryImportType.URLS_COUNT_HISTORY, URL_HISTORY_DATA_TYPE));
        sensors.add(createHistorySensor(IndexingHistoryImportType.EVENTS_COUNT_HISTORY, EVENT_HISTORY_DATA_TYPE));

        handleCommonMetricsService.handle(sensors, AVERAGE_SENSORS_SIZE);
    }

    private SolomonSensor createSamplesSensor(IndexingSamplesImportType importType, String dataType)
             {
        long now = System.currentTimeMillis();
        List<IndexingSamplesTableInfo> sampleTables = indexingSamplesTablesYDao.listAllTables();
        // берем последние для каждого из типов
        long lastUpdate = sampleTables.stream()
                .filter(info -> info.getState() == IndexingSamplesTableState.DONE && info.getImportType() == importType)
                .max(IndexingSamplesTableInfo.BY_TABLE_DATE_AND_UPDATE_TIME)
                .map(info -> info.getUpdateTime().getMillis()).orElse(now);

        return SolomonSensor.createAligned(refreshIntervalSeconds, (now - lastUpdate) / 1000L)
                .withLabel(SolomonSensor.LABEL_SECTION, INDEXING_SECTION_LABEL_VALUE)
                .withLabel(SolomonSensor.LABEL_INDICATOR, Indicators.DATA_AGE)
                .withLabel(SolomonSensor.LABEL_DATA_TYPE, dataType);
    }

    private SolomonSensor createHistorySensor(IndexingHistoryImportType importType, String dataType)
             {
        long now = System.currentTimeMillis();
        List<IndexingHistoryTableImport> urlHistoryTables = indexingHistoryTablesYDao.listImportsOfType(importType);
        long lastUpdate = urlHistoryTables.stream()
                .filter(info -> info.getState() == IndexingHistoryTableImportState.DONE)
                .max(IndexingHistoryTableImport.BY_TABLE_DATE_AND_UPDATE_TIME)
                .map(info -> info.getDataUpdateTime().getMillis()).orElse(now);
        return SolomonSensor.createAligned(refreshIntervalSeconds, (now - lastUpdate) / 1000L)
                .withLabel(SolomonSensor.LABEL_SECTION, INDEXING_SECTION_LABEL_VALUE)
                .withLabel(SolomonSensor.LABEL_INDICATOR, Indicators.DATA_AGE)
                .withLabel(SolomonSensor.LABEL_DATA_TYPE, dataType);
    }

}
