package ru.yandex.webmaster3.storage.addurl;

import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;

import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.addurl.RecrawlSendingStatus;
import ru.yandex.webmaster3.core.addurl.UrlRecrawlEventLog;
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.ydb.querybuilder.typesafe.ValueDataMapper;

/**
 * @author leonidrom
 * <p>
 * У таблицы TTL в 5 дней по полю update_date
 */
@Repository
public class AddUrlEventsLogsYDao extends AbstractYDao {
    private static final String TABLE_NAME = "recrawl_events_log";

    @Autowired
    public AddUrlEventsLogsYDao() {
        super("/webmaster3/addurl", TABLE_NAME);
    }

    public void add(UrlRecrawlEventLog log) {
        var st = upsert(
                F.URL_ID.value(log.getUrlId()),
                F.FULL_URL.value(log.getFullUrl()),
                F.UPDATE_DATE.value(log.getUpdateDate()),
                F.STATUS.value(log.getStatus()),
                F.USER_IP.value(log.getUserIp()),
                F.USER_ID.value(log.getUserId())
        );

        execute(st);
    }

    public void addBatch(List<UrlRecrawlEventLog> logs) {
        batchInsert(VALUE_DATA_MAPPER, logs).execute();
    }

    public void deleteForUser(long userId) {
        var sel = select(PK_MAPPER).secondaryIndex(USER_ID_INDEX).where(F.USER_ID.eq(userId)).getStatement();
        delete().on(sel).execute();
    }

    public void foreachEvent(Consumer<UrlRecrawlEventLog> consumer) {
        streamReader(MAPPER, consumer);
    }

    private static final DataMapper<UrlRecrawlEventLog> MAPPER = DataMapper.create(
            F.URL_ID, F.FULL_URL, F.UPDATE_DATE, F.STATUS, F.USER_IP, F.USER_ID, UrlRecrawlEventLog::new
    );

    private static final ValueDataMapper<UrlRecrawlEventLog> VALUE_DATA_MAPPER = ValueDataMapper.create2(
        Pair.of(F.URL_ID, UrlRecrawlEventLog::getUrlId),
        Pair.of(F.FULL_URL, UrlRecrawlEventLog::getFullUrl),
        Pair.of(F.UPDATE_DATE, UrlRecrawlEventLog::getUpdateDate),
        Pair.of(F.STATUS, UrlRecrawlEventLog::getStatus),
        Pair.of(F.USER_IP, UrlRecrawlEventLog::getUserIp),
        Pair.of(F.USER_ID, UrlRecrawlEventLog::getUserId)
    );

    private static final DataMapper<Pair<String, UUID>> PK_MAPPER = DataMapper.create(
            F.FULL_URL, F.URL_ID, Pair::of
    );

    private static final class F {
        public static final Field<UUID> URL_ID = Fields.uuidField("url_id");
        public static final Field<String> FULL_URL = Fields.stringField("full_url");
        public static final Field<DateTime> UPDATE_DATE = Fields.jodaDateTimeField("update_date");
        public static final Field<RecrawlSendingStatus> STATUS = Fields.intEnumField("status", RecrawlSendingStatus.R);
        public static final Field<String> USER_IP = Fields.stringField("user_ip");
        public static final Field<Long> USER_ID = Fields.longField("user_id");
    }
}
