package com.atlassian.stash.internal.i18n;

import com.atlassian.stash.internal.i18n.cache.MessageCache;
import com.atlassian.stash.internal.i18n.cache.MessageKey;
import com.atlassian.stash.internal.i18n.cache.MessageMap;
import com.atlassian.stash.internal.i18n.cache.UnresolvedLocales;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;

import java.util.Locale;

public class MessageCacheTestUtils {

    @SuppressWarnings("unchecked")
    public static <T> MessageMap<T> appendAll(MessageMap<T> one, MessageMap... messages) {
        for (MessageMap m : messages) {
            one = one.append(m);
        }
        return one;
    }

    public static <T, V> MessageCache<T, V> getMessageCache(T key, MessageMap... messages) {
        MessageCache<T, V> messageCache = new MessageCache<>();
        messageCache.put(key, localeCache(appendAll(MessageMap.empty(), messages)));

        return messageCache;
    }

    /**
     * This is a very strange method, converting a map of messages which (potentially) contains multiple locales
     * into a {@link UnresolvedLocales} which must resolve those values "lazily".
     */
    public static <V> UnresolvedLocales<V> localeCache(MessageMap<V> map) {
        Multimap<Locale, MessageKey> index = Multimaps.index(map.keySet(), MessageKey::getLocale);

        UnresolvedLocales.Builder<V> localeBuilder = new UnresolvedLocales.Builder<>();
        for (Locale locale : index.keySet()) {
            localeBuilder.put(locale, () -> {
                MessageMap.Builder<V> mapBuilder = new MessageMap.Builder<>();
                for (MessageKey messageKey : index.get(locale)) {
                    mapBuilder.put(messageKey, map.get(messageKey.getKey(), ImmutableList.of(messageKey.getLocale())));
                }
                return mapBuilder.build();
            });
        }

        return localeBuilder.build();
    }

    public static <V> MessageMap<V> msg(String key, Locale locale, V value) {
        return new MessageMap.Builder<V>().put(new MessageKey(key, locale), value).build();
    }

    public static <V> UnresolvedLocales<V> msgCache(String key, Locale locale, V value) {
        return localeCache(msg(key, locale, value));
    }
}
