package com.github.fge.grappa.trace.parser;

import com.github.fge.grappa.parsers.EventBusParser;
import com.github.fge.grappa.rules.Rule;
import com.google.common.collect.Range;

import javax.annotation.Nonnull;
import java.util.Objects;

public class TraceEventParser
    extends EventBusParser<Object>
{
    protected final TraceEventBuilder builder = new TraceEventBuilder();
    protected final Range<Integer> range;

    public TraceEventParser()
    {
        this(Range.atLeast(0));
    }

    public TraceEventParser(final Integer maxEvents)
    {
        if (maxEvents < 0)
            throw new IllegalArgumentException("maxEvents must be positive");
        range = Range.atMost(maxEvents);
    }

    public TraceEventParser(@Nonnull final Range<Integer> range)
    {
        this.range = Objects.requireNonNull(range);
    }

    public Rule traceEvents()
    {
        return join(traceEvent()).using('\n').range(range);
    }

    public Rule traceEvent()
    {
        return sequence(
            eventType(), ';',
            index(), ';',
            level(), ';',
            matcher(), ';',
            matcherType(), ';',
            matcherClass(), ';',
            nanoSeconds(),
            post(builder)
        );
    }

    Rule eventType()
    {
        return sequence(digit(), builder.setType(match()));
    }

    Rule index()
    {
        return sequence(oneOrMore(digit()), builder.setIndex(match()));
    }

    Rule level()
    {
        return sequence(oneOrMore(digit()), builder.setLevel(match()));
    }

    Rule matcher()
    {
        return sequence(
            join(oneOrMore(noneOf("\\;"))).using("\\;").min(1),
            builder.setMatcher(match())
        );
    }

    Rule matcherType()
    {
        return sequence(digit(), builder.setMatcherType(match()));
    }

    Rule matcherClass()
    {
        return sequence(oneOrMore(noneOf(";")),
            builder.setMatcherClass(match()));
    }

    Rule nanoSeconds()
    {
        return sequence(oneOrMore(digit()), builder.setNanoseconds(match()));
    }
}

@@ -148,69 +148,43 @@
 om.g
-oogle.common.collect.Range;%0A%0Aimport javax.annotation.Nonnull;
+ithub.fge.grappa.trace.TraceEvent;%0A
 %0Aimp
@@ -264,21 +264,25 @@
 sParser%3C
-Objec
+TraceEven
 t%3E%0A%7B%0A   
@@ -327,429 +327,70 @@
 lder
- = new TraceEventBuilder();%0A    protected final Range%3CInteger%3E range;%0A%0A    public TraceEventParser()%0A    %7B%0A        this(Range.atLeast(0));%0A    %7D%0A%0A    public TraceEventParser(final Integer maxEvents)%0A    %7B%0A        if (maxEvents %3C 0)%0A            throw new IllegalArgumentException(%22maxEvents must be positive%22);%0A        range = Range.atMost(maxEvents);%0A    %7D%0A%0A    public TraceEventParser(@Nonnull final Range%3CInteger%3E range
+;%0A%0A    public TraceEventParser(final TraceEventBuilder builder
 )%0A  
@@ -406,21 +406,23 @@
    this.
-range
+builder
  = Objec
@@ -443,116 +443,15 @@
 ull(
-range);%0A    %7D%0A%0A    public Rule traceEvents()%0A    %7B%0A        return join(traceEvent()).using('%5Cn').range(range
+builder
 );%0A 
@@ -735,19 +735,19 @@
    p
-ost
+ush
 (builder
 )%0A  
@@ -738,24 +738,32 @@
 push(builder
+.build()
 )%0A        );

make it parse one event only