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

import org.joda.time.Instant;
import ru.yandex.webmaster3.storage.searchurl.offline.data.SearchBaseImportInfo;

import static ru.yandex.webmaster3.storage.searchurl.samples.dao.CommonSearchUrlSamplesTableUtil.*;

/**
 * @author avhaliullin
 */
public class SearchUrlEventSampleTablesUtil {
    public static final String DB_NAME = "webmaster3_searchurls";
    public static final String DISTRIB_SYMLINK_TABLE = "search_url_event_samples_distrib";

    public static final String EVENTS_TABLE_INSERT_SPEC = "(" +
            "base_date, " +
            "host_id, " +
            "path, " +
            "last_access, " +
            "event_type, " +
            "title, " +
            "status, " +
            "ex_region, " +
            "ex_add_time, " +
            "ex_beauty_url, " +
            "ex_http_code, " +
            "ex_main_host, " +
            "ex_main_path, " +
            "ex_main_region, " +
            "ex_redir_target, " +
            "ex_rel_canonical_target, " +
            "ex_is_fake, " +
            "ex_is_indexed, " +
            "ex_is_turbo, " +
            "ex_is_from_sitemap, " +
            "ex_is_searchable," +
            "ex_turbo_source_flags," +
            "ex_valid_from_metrika_last_access," +
            "ex_valid_from_indexnow_last_access" +
            ") FORMAT TabSeparated";

    private static final String EVENT_TABLE_FIELDS_DECLARATION = "(" +
            "base_date Int64, " +
            "host_id String, " +
            "path String, " +
            "last_access Int64, " +
            "event_type Int8, " +
            "title String, " +
            "status Int8, " +
            "ex_region String, " +
            "ex_add_time Int64, " +
            "ex_beauty_url String, " +
            "ex_http_code Int32, " +
            "ex_main_host String, " +
            "ex_main_path String, " +
            "ex_main_region String, " +
            "ex_redir_target String, " +
            "ex_rel_canonical_target String, " +
            "ex_is_fake Int8, " +
            "ex_is_indexed Int8, " +
            "ex_is_turbo Int8, " +
            "ex_is_from_sitemap Int8, " +
            "ex_is_searchable Int8," +
            "ex_turbo_source_flags Int64,"+
            "ex_valid_from_metrika_last_access Int64," +
            "ex_valid_from_indexnow_last_access Int64" +
            ")";

    private static String eventsBaseTableName(Instant baseDate) {
        return String.format("search_url_event_samples_%s", searchBaseName(baseDate));
    }

    private static String eventsPartTableNamePrefix(Instant baseDate) {
        return partTablePrefix(eventsBaseTableName(baseDate));
    }

    public static String eventsPartTableName(Instant baseDate, int part) {
        return eventsPartTableNamePrefix(baseDate) + part;
    }

    public static String eventsTableCreateSpec(Instant baseDate, int part) {
        return String.format(EVENT_TABLE_FIELDS_DECLARATION +
                        " ENGINE = ReplicatedMergeTree('/webmaster3/clickhouse/tables/{shard}/search_url_event_samples_%s/part%d', '{replica}') " +
                        "PARTITION BY cityHash64(host_id) %% 16 ORDER BY (host_id, base_date, path)",
                searchBaseName(baseDate),
                part
        );
    }

    public static String eventsShardTableName(Instant baseDate) {
        return shardTableName(eventsBaseTableName(baseDate));
    }

    public static String eventsDistributedTableName(Instant baseDate) {
        return distributedTableName(eventsBaseTableName(baseDate));
    }

    public static String eventsShardCreateQuery(SearchBaseImportInfo info) {
        return "CREATE TABLE IF NOT EXISTS " + info.getDbName() + "." + eventsShardTableName(info.getSearchBaseDate()) + EVENT_TABLE_FIELDS_DECLARATION +
                " ENGINE = Merge('" + info.getDbName() + "', '^" + eventsPartTableNamePrefix(info.getSearchBaseDate()) + "')";
    }

    public static String eventsDistributedCreateQuery(SearchBaseImportInfo info) {
        return "CREATE TABLE IF NOT EXISTS " + info.getDbName() + "." + eventsDistributedTableName(info.getSearchBaseDate()) + EVENT_TABLE_FIELDS_DECLARATION +
                " ENGINE = Distributed('{cluster}', '" + info.getDbName() + "', '" + eventsShardTableName(info.getSearchBaseDate()) + "')";
    }

    public static String eventsDropSymlinkQuery() {
        return "DROP TABLE IF EXISTS " + DB_NAME + "." + DISTRIB_SYMLINK_TABLE;
    }

    public static String eventsCreateSymlinkQuery(SearchBaseImportInfo info) {
        return "CREATE TABLE IF NOT EXISTS " + info.getDbName() + "." + DISTRIB_SYMLINK_TABLE + EVENT_TABLE_FIELDS_DECLARATION +
                " ENGINE = Distributed('{cluster}', '" + info.getDbName() + "', '" + eventsShardTableName(info.getSearchBaseDate()) + "')";
    }
}
