/*
 * LapisCommons
 * Copyright (c) 2014, Lapis <https://github.com/LapisBlue>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package blue.lapis.common.command.impl;

import blue.lapis.common.command.Tokenizer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

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

/**
 * Reference implementation of the Tokenizer; generally splits on spaces, except inside quoted strings.
 */
public class StandardTokenizer implements Tokenizer {

    @Nonnull
    @Override
    public ImmutableList<String> getTokens(@Nonnull final String s) {
        List<String> result = Lists.newArrayList();

        String token = "";
        char delimiter = ' ';
        for (int i = 0; i < s.length(); i++) {
            char cur = s.charAt(i);

            if (delimiter != ' ') {
                if (cur != delimiter) {
                    token += cur;
                } else {
                    delimiter = ' ';
                    result.add(token);
                    token = "";
                }
            } else {
                if (cur == '"') {
                    delimiter = '"';
                    continue;
                } else {
                    if (Character.isWhitespace(cur)) {
                        if (!token.isEmpty()) {
                            result.add(token);
                            token = "";
                        }
                    } else {
                        if (Character.isLetterOrDigit(cur)) {
                            token += cur;
                        } else {
                            //Commit both the existing token and this new symbol
                            if (!token.isEmpty()) {
                                result.add(token);
                                token = "";
                            }
                            result.add("" + cur);
                        }
                    }
                }
            }
        }
        if (!token.isEmpty()) result.add(token);

        return ImmutableList.copyOf(result);
    }
}

@@ -1713,16 +1713,23 @@
   String
+Builder
  token =
@@ -1721,34 +1721,51 @@
 Builder token = 
-%22%22
+new StringBuilder()
 ;%0A        char d
@@ -1957,39 +1957,44 @@
            token
- += 
+.append(
 cur
+)
 ;%0A              
@@ -2069,32 +2069,43 @@
 result.add(token
+.toString()
 );%0A             
@@ -2108,38 +2108,65 @@
            token
- = %22%22;
+.setLength(0); // Reset the token
 %0A               
@@ -2264,38 +2264,8 @@
 %22';%0A
-                    continue;%0A
     
@@ -2368,32 +2368,34 @@
     if (
-!
 token.
-isEmpty()
+length() %3E 0
 ) %7B%0A    
@@ -2426,32 +2426,43 @@
 result.add(token
+.toString()
 );%0A             
@@ -2473,37 +2473,45 @@
            token
- = %22%22
+.setLength(0)
 ;%0A              
@@ -2650,15 +2650,20 @@
 oken
- += 
+.append(
 cur
+)
 ;%0A  
@@ -2806,32 +2806,34 @@
     if (
-!
 token.
-isEmpty()
+length() %3E 0
 ) %7B%0A    
@@ -2876,16 +2876,27 @@
 dd(token
+.toString()
 );%0A     
@@ -2931,13 +2931,21 @@
 oken
- = %22%22
+.setLength(0)
 ;%0A  
@@ -3015,17 +3015,28 @@
 add(
-%22%22 + 
+String.valueOf(
 cur)
+)
 ;%0A  
@@ -3139,24 +3139,26 @@
 if (
-!
 token.
-isEmpty()
+length() %3E 0
 ) re
@@ -3171,16 +3171,27 @@
 dd(token
+.toString()
 );%0A%0A    

Use a StringBuilder directly to save some performance