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

import java.util.List;

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

import ru.yandex.webmaster3.storage.WebmasterStorageException;
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.ClickhouseException;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseServer;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.OrderBy;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.Statement;

/**
 * @author akhazhoyan 08/2018
 */
@Repository
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public final class MdbDomainsOnSearchCHDao extends AbstractClickhouseDao {

    private static final String TABLE_NAME_PREFIX = "domains_on_search_";
    public static final CHTable TABLE = CHTable.builder()
            .database(DB_WEBMASTER3_CHECKLIST)
            .name(TABLE_NAME_PREFIX + "%s")
            .partitionBy("cityHash64(owner) % 16")
            .keyField(F.OWNER, CHPrimitiveType.String)
            .keyField(F.DOMAIN, CHPrimitiveType.String)
            .sharded(true)
            .build();

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

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

    public List<String> getDomainsWithPagination(String owner, int offset, int pageSize) throws ClickhouseException {
        ClickhouseTableInfo table = tableProvider.getTable(TableType.DOMAINS_ON_SEARCH);
        Statement statement = QueryBuilder.select(F.DOMAIN)
                .from(table.getLocalTableName())
                .where(QueryBuilder.eq(F.OWNER, owner))
                .orderBy(F.DOMAIN, OrderBy.Direction.ASC)
                .limit(offset, pageSize);
        return getClickhouseServer().queryAll(table.chContext(getClickhouseServer(), owner), statement, row -> row.getString(F.DOMAIN));
    }

    public int countDomains(String owner) throws WebmasterStorageException {
        ClickhouseTableInfo table = tableProvider.getTable(TableType.DOMAINS_ON_SEARCH);
        Statement select = QueryBuilder.select()
                .countAll()
                .from(table.getLocalTableName())
                .where(QueryBuilder.eq(F.OWNER, owner));
        return getClickhouseServer()
                .queryOne(table.chContext(getClickhouseServer(), owner), select, r -> r.getLongUnsafe(0))
                .map(Long::intValue)
                .orElse(0);
    }

    private static class F {
        static final String OWNER = "owner";
        static final String DOMAIN = "domain";
    }
}
