package ru.yandex.webmaster3.storage.feeds;

import java.util.Optional;
import java.util.function.Consumer;

import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.feeds.feed_domain.FeedDomainInfo;
import ru.yandex.webmaster3.core.feeds.feed_domain.FeedDomainSccStatus;
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 kravchenko99
 * @date 7/30/21
 */

@Repository
public class FeedsDomainInfoYDao extends AbstractYDao {
    private static final String TABLE_NAME = "feeds_domain_info";

    public FeedsDomainInfoYDao() {
        super(PREFIX_FEEDS, TABLE_NAME);
    }

    public Optional<FeedDomainInfo> get(String domain) {
        return Optional.ofNullable(select(MAPPER).where(F.DOMAIN.eq(domain)).queryOne());
    }

    public void update(FeedDomainInfo feedInfo) {
        upsert(VALUE_MAPPER, feedInfo).execute();
    }

    public FeedDomainInfo findById(long businessId) {
        return select(MAPPER)
                .secondaryIndex("business_index")
                .where(F.BUSINESS_ID.eq(businessId)).queryOne();
    }

    public void forEach(Consumer<FeedDomainInfo> consumer) {
        streamReader(MAPPER, consumer);
    }

    private static final DataMapper<FeedDomainInfo> MAPPER = DataMapper.create(
            F.DOMAIN, F.BUSINESS_ID, F.STATUS_SCC,
            F.START_SCC_TIMESTAMP, F.FINISH_SCC_TIMESTAMP, F.ERROR_SCC,
            FeedDomainInfo::new
    );

    private static final ValueDataMapper<FeedDomainInfo> VALUE_MAPPER = ValueDataMapper.create2(
            Pair.of(F.DOMAIN,          FeedDomainInfo::getDomain),
            Pair.of(F.BUSINESS_ID,     FeedDomainInfo::getBusinessId),
            Pair.of(F.STATUS_SCC,     FeedDomainInfo::getStatus)
    );

    private interface F {
        Field<String> DOMAIN = Fields.stringField("domain");
        Field<Long> BUSINESS_ID = Fields.longField("business_id");
        Field<FeedDomainSccStatus> STATUS_SCC = Fields.stringEnumField("status_scc", FeedDomainSccStatus.R).makeOptional();
        Field<DateTime> START_SCC_TIMESTAMP = Fields.jodaDateTimeField("start_scc_timestamp").makeOptional();
        Field<DateTime> FINISH_SCC_TIMESTAMP = Fields.jodaDateTimeField("finish_scc_timestamp").makeOptional();
        Field<String> ERROR_SCC = Fields.stringField("error_scc").makeOptional();
    }
}
