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

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

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.searchquery.Query;
import ru.yandex.webmaster3.core.searchquery.QueryId;
import ru.yandex.webmaster3.storage.clickhouse.LocalClickhouseTableProvider;
import ru.yandex.webmaster3.storage.clickhouse.TableProvider;
import ru.yandex.webmaster3.storage.clickhouse.TableType;
import ru.yandex.webmaster3.storage.clickhouse.table.Top3000QueriesTable;
import ru.yandex.webmaster3.storage.util.clickhouse2.AbstractClickhouseDao;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseEscapeUtils;

/**
 * @author aherman
 */
public class Top3000QueriesCHDao extends AbstractClickhouseDao {

    @Setter
    private TableProvider tableStorage;
    @Setter
    private String partSuffix;

    protected String getQueryIdsString(List<QueryId> queryIds) {
        return queryIds.stream().map(l -> Long.toString(l.getQueryId())).collect(Collectors.joining(","));
    }

    protected LocalClickhouseTableProvider getTableProvider() {
        return new Top3000QueriesTable(tableStorage.getTable(TableType.TOP_3000__QUERIES), partSuffix);
    }

    public List<Query> suggestQueries(WebmasterHostId hostId, String queryPart, int limit) {
        LocalClickhouseTableProvider table = getTableProvider();
        String likeClause = "";
        if (!StringUtils.isEmpty(queryPart)) {
            likeClause = " AND query_text LIKE '%" + ClickhouseEscapeUtils.trimAndEscape(queryPart) + "%'";
        }

        String q = "SELECT query_id, query_text FROM " + table.getTableName(getClickhouseServer(), hostId)
                + " WHERE host_id='" + hostId.toStringId() + "' "
                + " " + likeClause
                + " LIMIT " + limit;

        return getClickhouseServer().queryAll(table.chContext(getClickhouseServer(), hostId), q, row -> {
            long queryId = row.getLongUnsafe("query_id");
            String queryText = row.getString("query_text");
            return new Query(hostId, new QueryId(queryId), queryText);
        });
    }

    public List<Pair<QueryId, String>> getQueries(WebmasterHostId hostId, List<QueryId> queryIds) {
        LocalClickhouseTableProvider table = getTableProvider();
        if (queryIds.isEmpty()) {
            return Collections.emptyList();
        }
        String q = "SELECT distinct query_id, query_text FROM " + table.getTableName(getClickhouseServer(), hostId)
                + " WHERE host_id = '" + hostId.toStringId() + "'"
                + " AND query_id IN (" + getQueryIdsString(queryIds) + ")";

        return getClickhouseServer().queryAll(table.chContext(getClickhouseServer(), hostId), q, row -> {
            long queryId = row.getLongUnsafe("query_id");
            String query = row.getString("query_text");

            return Pair.of(new QueryId(queryId), query);
        });
    }


}
