package org.monospark.spongematchers.parser.element;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.monospark.spongematchers.util.PatternBuilder;

import com.google.common.collect.Maps;

public final class MapElementParser extends StringElementParser {

    private static final Pattern ENTRY_PATTERN = new PatternBuilder()
            .appendCapturingPart("[^\\{\\},:]+", "entryname")
            .appendNonCapturingPart("\\s*:\\s*")
            .appendCapturingPart(StringElementParser.REPLACE_PATTERN, "entrycontent")
            .build();
    
    MapElementParser() {}
    
    @Override
    Pattern createPattern() {
        Pattern entryPattern = new PatternBuilder()
                .appendNonCapturingPart("[^\\{\\},:]+")
                .appendNonCapturingPart("\\s*:\\s*")
                .appendNonCapturingPart(StringElementParser.REPLACE_PATTERN)
                .build();
        return new PatternBuilder()
                .appendNonCapturingPart("\\{")
                .appendNonCapturingPart(entryPattern)
                .openAnonymousParantheses()
                    .appendNonCapturingPart("\\s*,\\s*")
                    .appendNonCapturingPart(entryPattern)
                .closeParantheses()
                .zeroOrMore()
                .appendNonCapturingPart("\\}")
                .build();
    }

    @Override
    void parse(Matcher matcher, StringElementContext context) {
        createMap(matcher, context);
    }
    
    private void createMap(Matcher matcher, StringElementContext context) {
        Map<String,StringElement> entries = Maps.newHashMap();
        Matcher entryMatcher = ENTRY_PATTERN.matcher(matcher.group());
        while (entryMatcher.find()) {
            String name = matcher.group("entryname");
            StringElement element = context.getElementAt(entryMatcher.start(), entryMatcher.end());
            context.removeElement(element);
            entries.put(name, element);
        }
        context.addElement(new MapElement(matcher.start(), matcher.end(), entries));;
    }
}

@@ -134,16 +134,88 @@
 ttern;%0A%0A
+import org.monospark.spongematchers.parser.SpongeMatcherParseException;%0A
 import o
@@ -1526,131 +1526,42 @@
 xt) 
-%7B%0A        createMap(matcher, context);%0A    %7D%0A    %0A    private void createMap(Matcher matcher, StringElementContext context)
+throws SpongeMatcherParseException
  %7B%0A 
@@ -1757,17 +1757,22 @@
  name = 
-m
+entryM
 atcher.g
@@ -1866,18 +1866,52 @@
 r.start(
-),
+%22entrycontent%22),%0A                   
  entryMa
@@ -1920,16 +1920,30 @@
 her.end(
+%22entrycontent%22
 ));%0A    
@@ -2032,16 +2032,16 @@
       %7D%0A
+
         
@@ -2116,17 +2116,16 @@
 tries));
-;
 %0A    %7D%0A%7D

Fix some map matcher parsing bugs