package ru.yandex.webmaster3.storage.searchurl.history.dao;

import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.util.W3Collectors;
import ru.yandex.webmaster3.storage.searchurl.history.data.SearchUrlStat;
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.MdbClickhouseServer;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;

/**
 * Created by Oleg Bazdyrev on 04/03/2021.
 */
@Slf4j
@Repository
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class LastSiteStructureCHDao extends AbstractClickhouseDao {

    public static final int PARTITIONS_COUNT = 32;
    public static final CHTable TABLE = CHTable.builder()
            .database(DB_WEBMASTER3_SEARCHURLS)
            .sharded(false)
            .parts(1)
            .name("last_site_structures_%s")
            .partitionBy("cityHash64(" + F.HOST_ID + ") % " + PARTITIONS_COUNT)
            .keyField(F.HOST_ID, CHPrimitiveType.String)
            .field(F.NUM_OF_DOCS, CHPrimitiveType.Int64)
            .field(F.NUM_OF_DOCS_ON_SEARCH, CHPrimitiveType.Int64)
            .field(F.NUM_OF_NEW_SEARCH_DOCS, CHPrimitiveType.Int64)
            .field(F.NUM_OF_GONE_SEARCH_DOCS, CHPrimitiveType.Int64)
            .build();

    private final MdbClickhouseServer legacyMdbClickhouseServer;

    @Override
    protected ClickhouseServer getClickhouseServer() {
        return legacyMdbClickhouseServer;
    }

    public Map<WebmasterHostId, SearchUrlStat> getSearchUrlStats(Collection<WebmasterHostId> hostIds, Instant baseDate) {
        var st = QueryBuilder.select(F.HOST_ID, F.NUM_OF_DOCS_ON_SEARCH, F.NUM_OF_NEW_SEARCH_DOCS, F.NUM_OF_GONE_SEARCH_DOCS)
                .from(DB_WEBMASTER3_SEARCHURLS, String.format(TABLE.getName(), baseDate.getMillis()))
                .where(QueryBuilder.in(F.HOST_ID, hostIds));
        return getClickhouseServer().queryAll(st.toString(), chRow ->
                new SearchUrlStat(chRow.getHostId(F.HOST_ID), baseDate, chRow.getLong(F.NUM_OF_DOCS_ON_SEARCH),
                chRow.getLong(F.NUM_OF_NEW_SEARCH_DOCS), chRow.getLong(F.NUM_OF_GONE_SEARCH_DOCS))
        ).stream().collect(Collectors.toMap(SearchUrlStat::getHostId, Function.identity(), W3Collectors.replacingMerger()));
    }

    private interface F {
        String HOST_ID = "host_id";
        String NUM_OF_DOCS = "num_of_docs";
        String NUM_OF_DOCS_ON_SEARCH = "num_of_docs_on_search";
        String NUM_OF_NEW_SEARCH_DOCS = "num_of_new_search_docs";
        String NUM_OF_GONE_SEARCH_DOCS = "num_of_gone_search_docs";
    }

}
