package com.mattunderscore.specky.model.generator.scope;

import static java.util.regex.Pattern.compile;

import java.util.function.Function;
import java.util.regex.Pattern;

import com.mattunderscore.specky.context.file.TemplateContext;

/**
 * Function to evaluate a template.
 * @author Matt Champion 27/02/2017
 */
public final class EvaluateTemplate implements Function<String, String> {
    private static final Pattern TYPE_PATTERN = compile("(?<!\\\\)\\$\\{type}");
    private static final Pattern AUTHOR_PATTERN = compile("(?<!\\\\)\\$\\{author}");
    private static final Pattern COPYRIGHT_HOLDER_PATTERN = compile("(?<!\\\\)\\$\\{copyrightHolder}");
    private static final Pattern ESCAPED_TYPE_PATTERN = compile("\\\\\\$\\{type}");
    private static final Pattern ESCAPED_AUTHOR_PATTERN = compile("\\\\\\$\\{author}");
    private static final Pattern ESCAPED_COPYRIGHT_HOLDER_PATTERN = compile("\\\\\\$\\{copyrightHolder}");

    private final TemplateContext templateContext;

    /**
     * Constructor.
     */
    public EvaluateTemplate(TemplateContext templateContext) {
        this.templateContext = templateContext;
    }

    @Override
    public String apply(String template) {
        return
            replace(
                replace(
                    replace(
                        replace(
                            replace(
                                replace(
                                    template,
                                    TYPE_PATTERN,
                                    templateContext.getTypeName()),
                                AUTHOR_PATTERN,
                                templateContext.getAuthor()),
                            COPYRIGHT_HOLDER_PATTERN,
                            templateContext.getCopyrightHolder()),
                        ESCAPED_TYPE_PATTERN,
                        "\\${type}"),
                    ESCAPED_AUTHOR_PATTERN,
                    "\\${author}"),
                ESCAPED_COPYRIGHT_HOLDER_PATTERN,
                "\\${copyrightHolder}");
    }

    private static String replace(String template, Pattern pattern, String substitution) {
        return pattern.matcher(template).replaceAll(substitution);
    }
}

@@ -422,23 +422,45 @@
 tern
- TYPE_
+%5B%5D 
 PATTERN
+S
  =
+ new Pattern%5B%5D %7B%0A       
  com
@@ -491,59 +491,17 @@
 e%7D%22)
-;
+,
 %0A    
-private static final Pattern AUTHOR_PATTERN =
+   
  com
@@ -534,69 +534,17 @@
 r%7D%22)
-;
+,
 %0A    
-private static final Pattern COPYRIGHT_HOLDER_PATTERN =
+   
  com
@@ -586,65 +586,17 @@
 r%7D%22)
-;
+,
 %0A    
-private static final Pattern ESCAPED_TYPE_PATTERN =
+   
  com
@@ -622,67 +622,17 @@
 e%7D%22)
-;
+,
 %0A    
-private static final Pattern ESCAPED_AUTHOR_PATTERN =
+   
  com
@@ -660,77 +660,17 @@
 r%7D%22)
-;
+,
 %0A    
-private static final Pattern ESCAPED_COPYRIGHT_HOLDER_PATTERN =
+   
  com
@@ -703,18 +703,23 @@
 older%7D%22)
-;
 %0A
+    %7D;
 %0A    pri
@@ -733,39 +733,30 @@
 nal 
-TemplateContext templateContext
+String%5B%5D substitutions
 ;%0A%0A 
@@ -865,433 +865,82 @@
     
-this.templateContext = templateContext;%0A    %7D%0A%0A    @Override%0A    public String apply(String template) %7B%0A        return%0A            replace(%0A                replace(%0A                    replace(%0A                        replace(%0A                            replace(%0A                                replace(%0A                                    template,%0A                                    TYPE_PATTERN,%0A                        
+substitutions = new String%5B%5D %7B%0A            templateContext.getTypeName(),%0A
     
@@ -970,89 +970,18 @@
 .get
-TypeName
+Author
 ()
-)
 ,%0A
-                                AUTHOR_PATTERN,%0A                    
     
@@ -1011,17 +1011,25 @@
 .get
-Autho
+CopyrightHolde
 r()
-)
 ,%0A  
@@ -1042,98 +1042,66 @@
     
-       
-         COPYRIGHT_HOLDER_PATTERN,%0A                            templateContext.getC
+%22%5C%5C$%7Btype%7D%22,%0A            %22%5C%5C$%7Bauthor%7D%22,%0A            %22%5C%5C$%7Bc
 opyr
@@ -1114,12 +1114,10 @@
 lder
-()),
+%7D%22
 %0A   
@@ -1117,32 +1117,36 @@
 r%7D%22%0A        
+%7D;%0A%0A
         
         ESCA
@@ -1137,205 +1137,330 @@
     
-        ESCAPED_TYPE_PATTERN,%0A           
+assert substitutions.length == PATTERNS.length : %22Must be the same number of patterns and substitutions%22;%0A
     
+%7D%0A%0A
     
-     %22%5C%5C$%7Btype%7D%22),%0A                    ESCAPED_AUTHOR_PATTERN,%0A                    %22%5C%5C$%7Bauthor%7D%22),%0A                ESCAPED_COPYRIGHT_HOLDER_PATTERN,
+@Override%0A    public String apply(String template) %7B%0A        String value = template;%0A%0A        for (int i = 0; i %3C PATTERNS.length; i++) %7B%0A            value = replace(value, PATTERNS%5Bi%5D, substitutions%5Bi%5D);
 %0A   
@@ -1460,32 +1460,35 @@
 %5D);%0A        
+%7D%0A%0A
         
 %22%5C%5C$%7Bcopyrig
@@ -1479,31 +1479,20 @@
     
-%22%5C%5C$%7BcopyrightHolder%7D%22)
+return value
 ;%0A  

Refactor templates and substitutions to be easier to introduce new ones.