package com.github.richardjwild.randomizer.types.pattern.parserstate;

import com.github.richardjwild.randomizer.types.pattern.StringPatternBuilder;
import com.github.richardjwild.randomizer.types.pattern.StringPatternParser;
import com.github.richardjwild.randomizer.types.pattern.StringPatternParserException;

import java.util.List;

import static com.github.richardjwild.randomizer.localization.Messages.*;
import static java.lang.Integer.parseInt;

public class DefineRangeLengthState extends ParserState {

    private final List<Character> permittedCharacters;
    private final StringBuilder lengthBuilder = new StringBuilder();

    public DefineRangeLengthState(StringPatternParser parser, StringPatternBuilder builder, List<Character> permittedCharacters) {
        super(parser, builder);
        this.permittedCharacters = permittedCharacters;
    }

    @Override
    public ParserState handleCharacter(char c) {
        ParserState nextState = this;
        if (c == '}') {
            setElementLength(lengthBuilder.toString());
            nextState = new DefineLiteralPatternState(parser, builder);
        } else {
            lengthBuilder.append(c);
        }
        return nextState;
    }

    @Override
    public void patternEnded() {
        if (lengthBuilder.length() == 0)
            throw new StringPatternParserException(UNEXPECTED_PATTERN_END_WANTED_NUMBER);
        throw new StringPatternParserException(UNEXPECTED_PATTERN_END_WANTED_NUMBER_COMMA_CLOSECURLYBRACE);
    }

    private void setElementLength(String elementLengthDefinition) {
        String[] parts = elementLengthDefinition.split(",");
        switch (parts.length) {
            case 1:
                if (elementLengthDefinition.endsWith(","))
                    throw new StringPatternParserException(MISSING_VALUE_IN_LENGTH_DEFINITION);
                builder.addFixedLengthElement(readInt(parts[0]), permittedCharacters);
                break;
            case 2:
                builder.addRandomLengthElement(readInt(parts[0]), readInt(parts[1]), permittedCharacters);
                break;
            default:
                throw new StringPatternParserException(TOO_MANY_FIELDS_IN_LENGTH_DEFINITION,
                        Integer.valueOf(parts.length).toString());
        }
    }

    private int readInt(String s) {
        if (s.isEmpty())
            throw new StringPatternParserException(MISSING_VALUE_IN_LENGTH_DEFINITION);
        return tryParseInt(s);
    }

    private int tryParseInt(String s) {
        try {
            return parseInt(s);
        } catch (NumberFormatException e) {
            throw new StringPatternParserException(INVALID_NUMBER_IN_LENGTH_DEFINITION);
        }
    }
}

@@ -924,46 +924,8 @@
 ) %7B%0A
-        ParserState nextState = this;%0A
     
@@ -940,24 +940,24 @@
 c == '%7D') %7B%0A
+
             
@@ -1016,19 +1016,14 @@
     
-nextState =
+return
  new
@@ -1121,30 +1121,24 @@
 end(c);%0A    
-    %7D%0A
         retu
@@ -1144,18 +1144,23 @@
 urn 
-nextState;
+this;%0A        %7D
 %0A   

Refactor DefineRangeLengthState for greater clarity