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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.jetbrains.annotations.TestOnly;

import ru.yandex.qe.dispenser.domain.base_resources.BaseResourceMapping;

@TestOnly
public class BaseResourceMappingDaoImpl implements BaseResourceMappingDao {

    private final List<BaseResourceMapping> collection = new ArrayList<>();

    @Override
    public synchronized BaseResourceMapping create(BaseResourceMapping.Builder builder) {
        long nextId = collection.stream().max(Comparator.comparing(BaseResourceMapping::getId))
                .map(BaseResourceMapping::getId).orElse(-1L) + 1L;
        BaseResourceMapping result = builder.build(nextId);
        collection.add(result);
        return result;
    }

    @Override
    public synchronized Optional<BaseResourceMapping> getById(long id) {
        return collection.stream().filter(v -> v.getId() == id).findFirst();
    }

    @Override
    public synchronized Set<BaseResourceMapping> getByIds(Collection<? extends Long> ids) {
        if (ids.isEmpty()) {
            return Set.of();
        }
        return collection.stream().filter(v -> ids.contains(v.getId())).collect(Collectors.toSet());
    }

    @Override
    public synchronized List<BaseResourceMapping> getPage(Long idFrom, int size) {
        return Optional.ofNullable(idFrom).map(from -> collection.stream()
                        .sorted(Comparator.comparing(BaseResourceMapping::getId))
                .filter(v -> v.getId() > from).limit(size).collect(Collectors.toList()))
                .orElseGet(() -> collection.stream().sorted(Comparator.comparing(BaseResourceMapping::getId))
                        .limit(size).collect(Collectors.toList()));
    }

    @Override
    public synchronized Set<BaseResourceMapping> getByCampaign(long campaignId) {
        return collection.stream().filter(v -> v.getCampaignId() == campaignId).collect(Collectors.toSet());
    }

    @Override
    public synchronized Set<BaseResourceMapping> getByCampaigns(Collection<? extends Long> campaignIds) {
        if (campaignIds.isEmpty()) {
            return Set.of();
        }
        return collection.stream().filter(v -> campaignIds.contains(v.getCampaignId())).collect(Collectors.toSet());
    }

    @Override
    public synchronized Set<Long> getMappedBaseResourceIds(long campaignId, Collection<? extends Long> baseResourceIds) {
        if (baseResourceIds.isEmpty()) {
            return Set.of();
        }
        return collection.stream()
                .filter(v -> v.getCampaignId() == campaignId && baseResourceIds.contains(v.getBaseResourceId()))
                .map(BaseResourceMapping::getBaseResourceId)
                .collect(Collectors.toSet());
    }

    @Override
    public synchronized void clear() {
        collection.clear();
    }
}
