package ru.yandex.webmaster3.storage.sitemap.dao;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.checklist.data.SiteProblemContent;
import ru.yandex.webmaster3.core.checklist.data.SiteProblemState;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.storage.checklist.data.AbstractProblemInfo;
import ru.yandex.webmaster3.storage.checklist.data.RealTimeSiteProblemInfo;
import ru.yandex.webmaster3.storage.clickhouse.ClickhouseTableInfo;
import ru.yandex.webmaster3.storage.clickhouse.TableProvider;
import ru.yandex.webmaster3.storage.clickhouse.TableType;
import ru.yandex.webmaster3.storage.util.clickhouse2.AbstractClickhouseDao;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHPrimitiveType;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHTable;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseServer;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;

/**
 * Created by Oleg Bazdyrev on 16/03/2021.
 * TODO общий DAO для всех проблем, рассчитываемых на YT-е
 */
@Repository
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class SitemapProblemsCHDao extends AbstractClickhouseDao {

    @Qualifier("legacyMdbTableStorage")
    private final TableProvider tableProvider;
    @Qualifier("legacyMdbClickhouseServer")
    private final ClickhouseServer clickhouseServer;

    @Override
    public ClickhouseServer getClickhouseServer() {
        return clickhouseServer;
    }

    public List<? extends AbstractProblemInfo> getProblems(WebmasterHostId hostId) {
        return getProblems(Collections.singleton(hostId)).getOrDefault(hostId, Collections.emptyList());
    }

    @SuppressWarnings("unchecked")
    public Map<WebmasterHostId, List<? extends AbstractProblemInfo>> getProblems(Collection<WebmasterHostId> hostIds) {
        ClickhouseTableInfo table = tableProvider.getTable(TableType.SITEMAP_PROBLEMS);
        var st = QueryBuilder.select(F.HOST_ID, F.ACTUAL_SINCE, F.LAST_UPDATE, F.DATA)
                .from(table.getTableName())
                .where(QueryBuilder.in(F.HOST_ID, hostIds));
        return (Map<WebmasterHostId, List<? extends AbstractProblemInfo>>) (Map) getClickhouseServer().queryAll(st.toString(), chRow -> {
            WebmasterHostId hostId = chRow.getHostId(F.HOST_ID);
            DateTime actualSince = chRow.getDateTime(F.ACTUAL_SINCE);
            DateTime lastUpdate = chRow.getDateTime(F.LAST_UPDATE);
            SiteProblemContent content = JsonMapping.readValue(chRow.getString(F.DATA), SiteProblemContent.class);
            return new RealTimeSiteProblemInfo(hostId, lastUpdate, actualSince, null, SiteProblemState.PRESENT, content.getProblemType(), content, 0);
        }).stream().collect(Collectors.groupingBy(RealTimeSiteProblemInfo::getHostId));
    }

    public static final CHTable TABLE = CHTable.builder()
            .database(AbstractClickhouseDao.DB_WEBMASTER3_CHECKLIST)
            .name("sitemap_problems_%s")
            .sharded(false)
            .partitionBy("") // no partitioning
            .keyField(F.HOST_ID, CHPrimitiveType.String)
            .keyField(F.TYPE, CHPrimitiveType.String)
            .field(F.ACTUAL_SINCE, CHPrimitiveType.Int64)
            .field(F.LAST_UPDATE, CHPrimitiveType.Int64)
            .field(F.DATA, CHPrimitiveType.String)
            .build();

    public interface F {
        String HOST_ID = "host_id";
        String TYPE = "type";
        String ACTUAL_SINCE = "actual_since";
        String LAST_UPDATE = "last_update";
        String DATA = "data";
    }
}
