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

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;

import org.jetbrains.annotations.NotNull;

import ru.yandex.qe.dispenser.domain.index.IndexConsumer;
import ru.yandex.qe.dispenser.domain.index.LongIndexable;

public abstract class InMemoryLongKeyDaoImpl<T extends LongIndexable & IndexConsumer<Long>> extends InMemoryDaoImpl<T, Long> {
    protected InMemoryLongKeyDaoImpl() {
        super(new LongKeyProducer<>());
    }

    private static final class LongKeyProducer<T extends LongIndexable & IndexConsumer<Long>> implements Function<T, Long> {
        @NotNull
        private final Map<T, Long> cache = new ConcurrentHashMap<>();
        @NotNull
        private final AtomicLong counter = new AtomicLong();

        private final boolean isIndexDisabled = Boolean.valueOf(System.getProperty("disableIndexProducing", "False"));

        @NotNull
        @Override
        public Long apply(@NotNull final T obj) {
            if (isIndexDisabled) {
                if (obj.getId() >= 0) {
                    return obj.getId();
                } else {
                    throw new RuntimeException("index producing is disabled!");
                }
            } else {
                return cache.computeIfAbsent(obj, k -> obj.getId() >= 0 ? obj.getId() : counter.getAndIncrement());
            }
        }
    }
}
