package ru.yandex.qe.dispenser.domain.dao.bot.service.reserve;

import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import ru.yandex.qe.dispenser.domain.Campaign;
import ru.yandex.qe.dispenser.domain.Segment;
import ru.yandex.qe.dispenser.domain.dao.InMemoryLongKeyDaoImpl;

public class BotServiceReserveDaoImpl
        extends InMemoryLongKeyDaoImpl<BotServiceReserve>
        implements BotServiceReserveDao {
    @Override
    public Set<BotServiceReserve> getReservesByBigOrders(final Set<Campaign.CampaignIdOrderId> campaignOrderIds) {
        return filter(reserve -> campaignOrderIds.stream()
                .anyMatch(co -> Long.valueOf(co.getBigOrderId()).equals(reserve.getBigOrderId())
                        && Long.valueOf(co.getCampaignId()).equals(reserve.getCampaignId())))
                .collect(Collectors.toSet());
    }

    @Override
    public Stream<BotServiceReserve> getReserveStreamFiltered(final BotServiceReserveFilter filter) {
        Stream<BotServiceReserve> reserveStream = getAll().stream();
        if (!filter.getServices().isEmpty()) {
            reserveStream = reserveStream.filter(reserve -> filter.getServices().contains(reserve.getService()));
        }
        if (!filter.getBigOrderIds().isEmpty()) {
            reserveStream = reserveStream.filter(reserve -> filter.getBigOrderIds().contains(reserve.getBigOrderId()));
        }
        if (!filter.getCampaignIds().isEmpty()) {
            reserveStream = reserveStream.filter(reserve -> filter.getCampaignIds().contains(reserve.getCampaignId()));
        }
        if (!filter.getCampaignBigOrders().isEmpty()) {
            reserveStream = reserveStream.filter(reserve -> filter.getCampaignBigOrders().stream()
                    .anyMatch(co -> Long.valueOf(co.getBigOrderId()).equals(reserve.getBigOrderId())
                            && Long.valueOf(co.getCampaignId()).equals(reserve.getCampaignId())));
        }
        return reserveStream;
    }

    @Override
    public boolean hasReservesInCampaign(final long campaignId) {
        return getAll().stream().anyMatch(r -> Long.valueOf(campaignId).equals(r.getCampaignId()));
    }

    @Override
    public boolean hasReservesInCampaignForOrdersOtherThan(final long campaignId, final Set<Long> orderIds) {
        return getAll().stream().anyMatch(r -> Long.valueOf(campaignId).equals(r.getCampaignId()) && !orderIds.contains(r.getBigOrderId()));
    }

    @Override
    public void updateSegments(final long reserveId, final Set<Segment> segments) {
        final BotServiceReserve reserve = read(reserveId);
        final BotServiceReserve updated = new BotServiceReserve(
                new BotServiceReserve.Key(reserve.getResource(), segments, reserve.getBigOrderId(), reserve.getCampaignId()),
                reserve.getAmount()
        );
        updated.setId(reserveId);
        update(updated);
    }

}
