package com.box.l10n.mojito.service.machinetranslation;

import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Encodes placeholders to ensure that they will be protected during the (machine) translation process.
 * The placeholders patterns are defined in {@Link PlaceholderPatternType}.
 * Any string matching that pattern will get wrapped into a <span translate="no">pattern</span> block.
 *
 * @author garion
 */
@Component
public class PlaceholderEncoder {

    public Pattern getPlaceholderPattern() {
        String placeholderRegex = Arrays.stream(PlaceholderPatternType.values())
                .map(PlaceholderPatternType::getValue)
                .collect(Collectors.joining("|"));

        return Pattern.compile(placeholderRegex);
    }

    public List<String> encode(List<String> textSources) {
        return textSources.stream()
                .map(this::encode)
                .collect(Collectors.toList());
    }

    public String encode(String textSource) {
        Matcher matcher = getPlaceholderPattern().matcher(textSource);

        StringBuffer stringBuffer = new StringBuffer();
        while (matcher.find()) {
            String match = matcher.group();
            matcher.appendReplacement(
                    stringBuffer,
                    Matcher.quoteReplacement("<span translate=\"no\">" + match + "</span>"));
        }
        matcher.appendTail(stringBuffer);

        return stringBuffer.toString();
    }

    public List<String> decode(List<String> textSources) {
        return textSources.stream()
                .map(this::decode)
                .collect(Collectors.toList());
    }

    public String decode(String textSource) {
        // Note: ensure that matching is enabled across lines as well by using (?s), for content containing end lines.
        return textSource.replaceAll("<span translate=\"no\">(?s)(.*?)</span>", "$1");
    }
}

@@ -606,16 +606,270 @@
 coder %7B%0A
+    Pattern placeholderPattern;%0A%0A    // Note: ensure that matching is enabled across lines as well by using (?s), for content containing end lines.%0A    Pattern translateInstructionSpanPattern = Pattern.compile(%22%3Cspan translate=%5C%22no%5C%22%3E(?s)(.*?)%3C/span%3E%22);%0A
 %0A    pub
@@ -876,19 +876,8 @@
 lic 
-Pattern get
 Plac
@@ -883,23 +883,23 @@
 ceholder
-Patt
+Encod
 er
-n
 () %7B%0A   
@@ -1091,22 +1091,36 @@
         
-return
+placeholderPattern =
  Pattern
@@ -1146,32 +1146,119 @@
 rRegex);%0A    %7D%0A%0A
+    public Pattern getPlaceholderPattern() %7B%0A        return placeholderPattern;%0A    %7D%0A%0A
     public List%3C
@@ -1497,20 +1497,17 @@
 tcher = 
-getP
+p
 lacehold
@@ -1515,18 +1515,16 @@
 rPattern
-()
 .matcher
@@ -2180,134 +2180,55 @@
     
-// Note: ensure that matching is enabled across lines as well by using (?s), for content containing end lines.%0A        return 
+return translateInstructionSpanPattern.matcher(
 text
@@ -2233,16 +2233,17 @@
 xtSource
+)
 .replace
@@ -2250,51 +2250,8 @@
 All(
-%22%3Cspan translate=%5C%22no%5C%22%3E(?s)(.*?)%3C/span%3E%22, 
 %22$1%22

Create Regex patterns only on initialization