package com.atlassian.stash.internal.web.locale;

import com.atlassian.stash.internal.language.Language;
import com.atlassian.bitbucket.util.Chainable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import java.util.Locale;
import java.util.Map;
import java.util.function.Function;

import static com.atlassian.bitbucket.util.Chainable.chain;

/**
 * Some basic util methods to share between {@link AdminLocaleFormFragment} and
 * {@link com.atlassian.stash.internal.web.users.UserAccountController}.
 */
public class UserLocaleWebUtils {

    public static Map<String, Object> asData(String locale, String name) {
        return asData(locale, name, false);
    }

    public static Map<String, Object> asData(String locale, String name, boolean selected) {
        return ImmutableMap.<String, Object>of("locale", locale, "name", name, "selected", selected);
    }

    public static Chainable<Map<String, Object>> toSoy(Iterable<Language> languages, final String selected) {
        // TODO Add sorting here
        return chain(languages).transform(new Function<Language, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(Language language) {
                String locale = language.getLocale().toString();
                return asData(locale, language.getLocalizedName(), locale.equals(selected));
            }
        });
    }

    /**
     * Given a list of available languages and preferred locales, returns a Chainable containing language objects
     * and marks only the language that matches the first matching preferred locale as selected.
     */
    @SuppressWarnings("ConstantConditions")
    public static Chainable<Map<String, Object>> toSoy(final Iterable<Language> languages, final Iterable<Locale> preferredLocales) {
        final Locale selectedLocale = chain(preferredLocales).flatMap(new Function<Locale, Iterable<Locale>>() {
            @Override
            public Iterable<Locale> apply(Locale locale) {
                for (Language language : languages) {
                    if (language.getLocale().toString().equals(locale.toString())) {
                        return ImmutableList.of(locale);
                    }
                }
                return ImmutableList.of();
            }
        }).getFirst(Locale.US);

        return toSoy(languages, selectedLocale.toString());
    }
}
