package ru.yandex.webmaster3.core.semantic.review_business;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Date: 28/11/12
 * Author: Evgeny Zhoga (ezhoga@yandex-team.ru)
 */
public class Locales {
    // cache to store singleton Locales not presented in Locale class
    private final static Map<String, Locale> cache =
            new HashMap<String, Locale>(32);
    /**
     * Useful constant for language.
     */
    static public final Locale RUSSIAN = createSingleton("ru__", "ru", "");
    /**
     * Useful constant for language.
     */
    static public final Locale UKRANIAN = createSingleton("uk__", "uk", "");
    /**
     * Useful constant for language.
     */
    static public final Locale TURKISH = createSingleton("tr__", "tr", "");
    /**
     * Useful constant for language.
     */
    static public final Locale ENGLISH = createSingleton(Locale.ENGLISH);

    /**
     * Creates a <code>Locale</code> instance with the given
     * <code>language</code> and <code>counry</code> and puts the
     * instance under the given <code>key</code> in the cache. This
     * method must be called only when initializing the Locale
     * constants.
     */
    private static Locale createSingleton(String key, String language, String country) {
        Locale locale = new Locale(language, country);
        cache.put(key, locale);
        return locale;
    }

    private static Locale createSingleton(final Locale locale) {
        cache.put(locale.getLanguage() + "_" + locale.getCountry() + "_", locale);
        return locale;
    }

    private static String getKey(final String language, final String country) {
        Preconditions.checkNotNull(language);
        Preconditions.checkNotNull(country);

        StringBuilder key = new StringBuilder();
        if (language.length() > 2) {
            key.append(language.substring(0, 2).toLowerCase());
        } else {
            key.append(language.toLowerCase());
        }
        key.append("_");
        if (country.length() > 2) {
            key.append(country.substring(0, 2).toUpperCase());
        } else {
            key.append(country.toUpperCase());
        }
        key.append("_");

        return key.toString();
    }

    /**
     * Parse locale String and return presented in Cache supported languages.
     * If no language found (by pair language, region) will try to resolve language
     * by only one argument
     */
    public static Locale safeValueOf(final String locale) {
        if (locale == null) return null;
        String[] langAndCountry = locale.split("_");
        final Locale lang = cache.get(getKey(langAndCountry[0], langAndCountry.length > 1 ? langAndCountry[1] : ""));
        if (lang != null) return lang;
        return cache.get(getKey(langAndCountry[0], ""));
    }

    public static Locale safeValueOf(@NotNull final String language, @NotNull final String country) {
        final Locale lang = cache.get(getKey(language, country));
        if (lang != null) return lang;
        return cache.get(getKey(language, ""));
    }

    public static Locale recognize(final String code) {
        return safeValueOf(code);
    }

    /**
     * Return String representation of
     *
     * @param locale
     * @return
     */
    public static String toString(final Locale locale) {
        if (locale == null) return null;

        final StringBuilder sb = new StringBuilder("_");
        if (!Strings.isNullOrEmpty(locale.getLanguage())) {
            sb.append(locale.getLanguage());
        }
        if (!Strings.isNullOrEmpty(locale.getCountry())) {
            sb.append("_").append(locale.getCountry());
        }

        return Strings.emptyToNull(sb.substring(1));
    }
}

