package com.todoist.markup;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

class EmojiParser {
    private static final String EMOJI_STANDARD = "emojis_standard.json";
    private static final String EMOJI_TODOIST = "emojis_todoist.json";

    private static Map<String, String> sEmojiMap = new HashMap<>();
    private static Pattern sEmojiPattern;

    static Pattern getEmojiPattern() {
        if (sEmojiPattern == null) {
            try {
                init();
            } catch (IOException e) {
                // Ignore. Not perfect but very unlikely.
            }
        }

        return sEmojiPattern;
    }

    static String getEmoji(String key) {
        return sEmojiMap.get(key);
    }

    static synchronized void init() throws IOException {
        Map<String, String> todoistShortcuts = new HashMap<>();
        if (sEmojiMap.isEmpty()) {
            ObjectMapper mapper = new ObjectMapper();

            InputStream standardInputStream = null;
            InputStream todoistInputStream = null;
            ClassLoader classLoader = EmojiParser.class.getClassLoader();

            try {
                standardInputStream = classLoader.getResourceAsStream(EMOJI_STANDARD);
                sEmojiMap = mapper.readValue(standardInputStream, new TypeReference<HashMap<String, String>>() {
                });

                todoistInputStream = classLoader.getResourceAsStream(EMOJI_TODOIST);
                todoistShortcuts = mapper.readValue(todoistInputStream, new TypeReference<HashMap<String, String>>() {
                });

                sEmojiMap.putAll(todoistShortcuts);
            } finally {
                closeQuietly(standardInputStream);
                closeQuietly(todoistInputStream);
            }
        }

        if (sEmojiPattern == null) {
            StringBuilder patternBuilder = new StringBuilder();

            // Pattern for standard emojis.
            patternBuilder.append("(:[a-zA-Z\\p{L}0-9_’\\-\\.\\&]+:)");

            for(String shortcut : todoistShortcuts.keySet()) {
                patternBuilder.append("|");
                patternBuilder.append(Pattern.quote(shortcut));
            }

            sEmojiPattern = Pattern.compile(patternBuilder.toString());
        }
    }

    private static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e1) { /* Ignore. */ }
        }
    }
}

@@ -312,16 +312,109 @@
 arser %7B%0A
+    private static final String REGEXP_STANDARD_EMOJI = %22(:%5Ba-zA-Z%5C%5Cp%7BL%7D0-9_%E2%80%99%5C%5C-%5C%5C.%5C%5C&%5D+:)%22;%0A
     priv
@@ -2259,43 +2259,29 @@
 end(
-%22(:%5Ba-zA-Z%5C%5Cp%7BL%7D0-9_%E2%80%99%5C%5C-%5C%5C.%5C%5C&%5D+:)%22
+REGEXP_STANDARD_EMOJI
 );%0A%0A

Make standard emoji regexp constant