package ru.yandex.webmaster3.storage.turbo.dao.statistics;

import java.util.List;
import java.util.stream.Collectors;

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

import ru.yandex.webmaster3.core.turbo.model.statistics.TurboClicksDayStatistics;
import ru.yandex.webmaster3.core.turbo.model.statistics.TurboTopUrlInfo;
import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.storage.util.clickhouse2.AbstractClickhouseDao;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHPrimitiveType;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHRow;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHTable;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseQueryContext;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseServer;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.Statement;

/**
 * ishalaru
 * 07.02.2020
 **/

@RequiredArgsConstructor(onConstructor_ = {@Autowired})
@Repository
public class MdbTurboClicksDayStatisticsCHDao extends AbstractClickhouseDao {

    public static final String FULL_TABLE_NAME = "turbo_click_day_stats";
    public static final CHTable TABLE = CHTable.builder()
            .database(DB_WEBMASTER3_TURBO)
            .name("tmp_turbo_click_day_stats_%s")
            .sharded(true)
            .partitionBy("toYear(date)")
            .keyField(F.DOMAIN, CHPrimitiveType.String)
            .keyField(F.DATE, CHPrimitiveType.Date)
            .field(F.TOTAL_CLICKS, CHPrimitiveType.Int64)
            .field(F.TURBO_CLICKS, CHPrimitiveType.Int64)
            .field(F.AUTOPARSED_CLICKS, CHPrimitiveType.Int64)
            .field(F.TOP_URLS_WITHOUT_TURBO, CHPrimitiveType.String)
            .build();

    @Qualifier("legacyMdbClickhouseServer")
    private final ClickhouseServer clickhouseServer;

    public List<TurboClicksDayStatistics> list(String domain, LocalDate start, LocalDate end) {
        Statement query = QueryBuilder.select(F.DOMAIN, F.DATE, F.TOTAL_CLICKS, F.TURBO_CLICKS, F.AUTOPARSED_CLICKS)
                .from(TABLE.getDatabase(), FULL_TABLE_NAME)
                .where(QueryBuilder.eq(F.DOMAIN, domain))
                .and(QueryBuilder.gte(F.DATE, start))
                .and(QueryBuilder.lte(F.DATE, end));
        var ctx = ClickhouseQueryContext.useDefaults().setHost(getClickhouseServer().pickAliveHostOrFail(getShard(domain)));
        return getClickhouseServer().queryAll(ctx, query.toString(), (CHRow r) -> new TurboClicksDayStatistics(
                r.getString(F.DOMAIN),
                r.getLocalDate(F.DATE),
                r.getLong(F.TOTAL_CLICKS),
                r.getLong(F.TURBO_CLICKS),
                r.getLong(F.AUTOPARSED_CLICKS),
                null
        ));
    }

    public List<TurboTopUrlInfo> topUrlsWithoutTurbo(String domain, LocalDate date) {
        Statement query = QueryBuilder.select(F.TOP_URLS_WITHOUT_TURBO)
                .from(TABLE.getDatabase(), FULL_TABLE_NAME)
                .where(QueryBuilder.eq(F.DOMAIN, domain))
                .and(QueryBuilder.eq(F.DATE, date));
        var ctx = ClickhouseQueryContext.useDefaults().setHost(getClickhouseServer().pickAliveHostOrFail(getShard(domain)));
        return getClickhouseServer().queryAll(ctx, query.toString(),
                chRow -> JsonMapping.readValue(chRow.getString(F.TOP_URLS_WITHOUT_TURBO), TurboTopUrlInfo.LIST_REFERENCE)
        ).stream().flatMap(List::stream).collect(Collectors.toList());
    }

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

    public interface F {
        String DOMAIN = "domain";
        String DATE = "date";
        String TOTAL_CLICKS = "total_clicks";
        String TURBO_CLICKS = "turbo_clicks";
        String AUTOPARSED_CLICKS = "autoparsed_clicks";
        String TOP_URLS_WITHOUT_TURBO = "top_urls_without_turbo";
    }
}
