package ru.yandex.qe.dispenser.domain.dao.campaign;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.springframework.dao.EmptyResultDataAccessException;

import ru.yandex.qe.dispenser.domain.Campaign;
import ru.yandex.qe.dispenser.domain.CampaignForBot;
import ru.yandex.qe.dispenser.domain.CampaignUpdate;
import ru.yandex.qe.dispenser.domain.dao.InMemoryDao;

public interface CampaignDao extends InMemoryDao<Campaign, Long> {

    @NotNull
    List<Campaign> getAllSorted(@NotNull final Set<Campaign.Status> statuses);

    @NotNull
    default List<Campaign> getAllActiveSorted() {
        return getAllSorted(ImmutableSet.of(Campaign.Status.ACTIVE));
    }

    @NotNull
    default Optional<Campaign> getLastActive() {
        return getAllActiveSorted().stream().findFirst();
    }

    @NotNull
    default Optional<Campaign> getLastActiveDraft() {
        return getAllActiveSorted().stream().filter(c -> c.getType() == Campaign.Type.DRAFT).findFirst();
    }

    @NotNull
    Campaign readForUpdate(@NotNull final Long id) throws EmptyResultDataAccessException;

    void partialUpdate(@NotNull final Campaign current, @NotNull final CampaignUpdate update);

    List<Campaign.CampaignOrder> getCampaignOrders(@NotNull final Set<Long> ids);

    List<Campaign.CampaignOrder> getCampaignOrdersByOrderIds(@NotNull final Set<Long> bigOrderIds);

    @NotNull
    Optional<CampaignForBot> getActiveForBotIntegration();

    Map<Long, CampaignForBot> readForBot(@NotNull final Set<Long> ids);

    @NotNull
    Campaign readWithDeleted(@NotNull final Long id) throws EmptyResultDataAccessException;

    @NotNull
    Optional<Campaign> readOptional(final long id);

    Set<Campaign> readByIds(final Set<Long> ids);

    Optional<Campaign> getByKey(String key);

    @TestOnly
    Campaign insertForTest(Campaign campaign);
}
