package ru.yandex.qe.dispenser.domain.dao.history.request;

import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.qe.dispenser.api.v1.DiOrder;
import ru.yandex.qe.dispenser.domain.QuotaChangeRequestHistoryEvent;
import ru.yandex.qe.dispenser.domain.dao.InMemoryLongKeyDaoImpl;
import ru.yandex.qe.dispenser.domain.dao.quota.request.QuotaChangeRequestDao;
import ru.yandex.qe.dispenser.domain.dao.quota.request.QuotaChangeRequestReader;
import ru.yandex.qe.dispenser.domain.util.HistoryDaoUtils;
import ru.yandex.qe.dispenser.domain.util.RelativePage;
import ru.yandex.qe.dispenser.domain.util.RelativePageInfo;

import static ru.yandex.qe.dispenser.domain.util.CollectionUtils.ids;

public class QuotaChangeRequestHistoryDaoImpl extends InMemoryLongKeyDaoImpl<QuotaChangeRequestHistoryEvent> implements QuotaChangeRequestHistoryDao {

    @Autowired
    private QuotaChangeRequestDao quotaChangeRequestDao;

    @Override
    public RelativePage<QuotaChangeRequestHistoryEvent> readHistoryByRequest(final long requestId,
                                                                             final QuotaChangeRequestHistoryFilter historyFilter,
                                                                             final RelativePageInfo pageInfo,
                                                                             final DiOrder order) {
        final Stream<QuotaChangeRequestHistoryEvent> stream = filter(event -> event.getQuotaChangeRequestId() == requestId)
                .filter(HistoryDaoUtils.asPredicate(historyFilter));
        return HistoryDaoUtils.relativePage(stream, pageInfo, order);
    }

    @Override
    public void create(final Collection<QuotaChangeRequestHistoryEvent> events) {
        events.forEach(super::create);
    }

    @Override
    public QuotaChangeRequestHistoryEvent read(final long id) {
        return super.read(id);
    }

    @Override
    public RelativePage<QuotaChangeRequestHistoryEvent> read(final QuotaChangeRequestReader.QuotaChangeRequestFilter filter,
                                                             final QuotaChangeRequestHistoryFilter historyFilter,
                                                             final RelativePageInfo pageInfo,
                                                             final DiOrder order) {
        final Set<Long> requestIds = ids(quotaChangeRequestDao.read(filter));
        final Stream<QuotaChangeRequestHistoryEvent> stream = filter(e -> requestIds.contains(e.getQuotaChangeRequestId()))
                .filter(HistoryDaoUtils.asPredicate(historyFilter));
        return HistoryDaoUtils.relativePage(stream, pageInfo, order);
    }

    @Override
    public boolean clearBefore(final Instant moment) {
        final List<QuotaChangeRequestHistoryEvent> before = filter(e -> e.getUpdated().isBefore(moment))
                .collect(Collectors.toList());
        return deleteAll(before);
    }

    @Override
    public boolean clear() {
        return super.clear();
    }
}
