package ru.yandex.webmaster3.storage.indexing2.internal.dao;

import java.util.List;
import java.util.UUID;

import org.joda.time.DateTime;
import org.joda.time.Instant;
import org.joda.time.LocalDate;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryImportType;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryTableImport;
import ru.yandex.webmaster3.storage.indexing2.internal.data.IndexingHistoryTableImportState;
import ru.yandex.webmaster3.storage.util.ydb.AbstractYDao;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.DataMapper;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Field;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Fields;
import ru.yandex.webmaster3.storage.util.yt.YtPath;

/**
 * @author iceflame
 */
@Repository
public class IndexingHistoryTablesYDao extends AbstractYDao implements IndexingHistoryTablesRepository {

    public IndexingHistoryTablesYDao() {
        super(PREFIX_IMPORTER, "indexed_urls_count_tables");
    }

    public void insertImportInfo(IndexingHistoryTableImport imprt) {
        upsert(
                F.IMPORT_TYPE.value(imprt.getImportType()),
                F.TABLE_DATE.value(imprt.getTableDate()),
                F.DATA_UPDATE_DATE.value(imprt.getDataUpdateTime()),
                F.LAST_UPDATE.value(DateTime.now()),
                F.STATE.value(imprt.getState()),
                F.YT_PREPARED_TABLES.value(imprt.getYtPreparedTables()),
                F.IMPORT_MANAGER_TASK_ID.value(imprt.getImportManagerTaskId()),
                F.TMP_TABLE_NAME.value(imprt.getTmpTableName()),
                F.REPLICATION_MANAGER_TASK_ID.value(imprt.getReplicationManagerTaskId()),
                F.REPLACED_TABLE_NEW_NAME.value(imprt.getReplacedTableNewName())
        )
        .execute();
    }

    public List<IndexingHistoryTableImport> listImportsOfType(IndexingHistoryImportType importType) {
        return select(MAPPER).where(F.IMPORT_TYPE.eq(importType)).queryForList();
    }

    public IndexingHistoryTableImport getLatestInfoOfType(IndexingHistoryImportType importType) {
        return select(MAPPER)
                .where(F.IMPORT_TYPE.eq(importType))
                .order(F.TABLE_DATE.desc()).order(F.DATA_UPDATE_DATE.desc())
                .limit(1)
                .queryOne();
    }

    private static final DataMapper<IndexingHistoryTableImport> MAPPER = DataMapper.create(
            F.IMPORT_TYPE, F.TABLE_DATE, F.DATA_UPDATE_DATE, F.STATE, F.YT_PREPARED_TABLES, F.IMPORT_MANAGER_TASK_ID,
            F.TMP_TABLE_NAME, F.REPLICATION_MANAGER_TASK_ID, F.REPLACED_TABLE_NEW_NAME, IndexingHistoryTableImport::new
    );

    private interface F {
        Field<IndexingHistoryImportType> IMPORT_TYPE = Fields.stringEnumField("import_type", IndexingHistoryImportType.R);
        Field<LocalDate> TABLE_DATE = Fields.jodaDateField("table_date");
        Field<Instant> DATA_UPDATE_DATE = Fields.jodaInstantField("data_update_date");
        Field<DateTime> LAST_UPDATE = Fields.jodaDateTimeField("last_update");
        Field<IndexingHistoryTableImportState> STATE = Fields.stringEnumField("state", IndexingHistoryTableImportState.R).makeOptional();
        Field<List<YtPath>> YT_PREPARED_TABLES = Fields.jsonField2("yt_prepared_tables", Fields.YT_PATH_LIST_REFERENCE).makeOptional();
        Field<UUID> IMPORT_MANAGER_TASK_ID = Fields.uuidField("import_manager_task_id").makeOptional();
        Field<String> TMP_TABLE_NAME = Fields.stringField("tmp_table_name").makeOptional();
        Field<UUID> REPLICATION_MANAGER_TASK_ID = Fields.uuidField("replication_manager_task_id").makeOptional();
        Field<String> REPLACED_TABLE_NEW_NAME = Fields.stringField("replaced_table_new_name").makeOptional();
    }
}
