package ru.yandex.webmaster3.storage.feeds;

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

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

import ru.yandex.webmaster3.core.feeds.feed.ExternalFeedInfo;
import ru.yandex.webmaster3.core.feeds.feed.ExternalFeedType;
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 FeedsExternalYDao extends AbstractYDao {
    private static final String TABLE_NAME = "feeds_external";

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

    public List<ExternalFeedInfo> list(String domain) {
        return select(MAPPER)
                .where(F.DOMAIN.eq(domain)).queryForList(Pair.of(F.URL, ExternalFeedInfo::getUrl));
    }

    public void batchInsert(Collection<ExternalFeedInfo> infos, DateTime updateDate) {
        List<Pair<ExternalFeedInfo, DateTime>> items =
                infos.stream().map(x -> Pair.of(x, updateDate)).collect(Collectors.toList());
        batchInsert(VALUE_MAPPER, items).execute();
    }

    public void deleteBefore(DateTime updateDate) {
        delete().where(F.UPDATE_DATE.lt(updateDate)).execute();
    }

    private static final DataMapper<ExternalFeedInfo> MAPPER = DataMapper.create(
            F.DOMAIN, F.URL, F.TYPE,
            ExternalFeedInfo::new
    );
    private static final ValueDataMapper<Pair<ExternalFeedInfo, DateTime>> VALUE_MAPPER = ValueDataMapper.create2(
            Pair.of(F.DOMAIN, x-> x.getKey().getDomain()),
            Pair.of(F.URL, x-> x.getKey().getUrl()),
            Pair.of(F.TYPE, x-> x.getKey().getType()),
            Pair.of(F.UPDATE_DATE, Pair::getValue)
    );



    private interface F {
        Field<String> DOMAIN = Fields.stringField("domain");
        Field<String> URL = Fields.stringField("url");
        Field<ExternalFeedType> TYPE = Fields.intEnumField("type", ExternalFeedType.R);

        Field<DateTime> UPDATE_DATE = Fields.jodaDateTimeField("update_date");
    }
}
