package lc.mecha.nls;

import lc.mecha.log.MechaLogger;
import lc.mecha.log.MechaLoggerFactory;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * Central store for NLS messages. This is a singleton object, which loads message catalogs on-demand automatically
 * from bundled resource files. Facilities are provided to perform locale matching.
 *
 * @author Alex Leigh
 */
public class NlsStore {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(NlsStore.class);
    private final static NlsStore store = new NlsStore();
    private HashMap<String, NlsMessageBundle> bundles = new HashMap<>();

    public static NlsStore getStore() {
        return store;
    }

    public NlsMessageBundle getBundle(String prefix, Locale locale) {
        NlsMessageBundle bundle = bundles.get(prefix);

        if (bundle == null) {
            bundle = new NlsMessageBundle();
        }

        if (!bundle.getLocales().contains(locale)) {
            ResourceBundle b = ResourceBundle.getBundle(prefix.toLowerCase(), locale);
            if (b == null) {
                return null;
            }

            bundle = new NlsMessageBundle();

            Enumeration<String> keys = b.getKeys();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();
                String msg = b.getString(key);
                int msgId = Integer.parseInt(key);

                logger.debug("Found message. [prefix: {}] [locale: {}] [id: {}] [msg: {}]",
                        prefix, locale, msgId, msg);

                bundle.putMessage(new NlsMessage(prefix, msgId, msg), locale);
            }
            logger.info("Dynamically loaded NLS message bundle: [prefix: {}] [locale: {}]", prefix, locale);
            bundles.put(prefix, bundle);
        }
        return bundle;
    }

    public void throwException(String prefix, int msg) throws NlsException {
        throwException(prefix, msg, Locale.US);
    }

    public void throwException(String prefix, int msg, Locale locale) throws NlsException {
        NlsMessageBundle bundle = getBundle(prefix, locale);
        NlsMessage m = null;

        if (bundle != null) {
            m = bundle.getMessage(prefix, msg, locale);
        }

        if (m != null) {
            throw new NlsException(bundle.getMessage(prefix, msg, locale));
        }

        logger.warn("Could not find NLS message. [prefix: {}] [msg: {}] [locale: {}]", prefix, msg, locale);

        throw new NlsException(new NlsMessage(prefix, msg, ""));
    }
}
