package com.github.bot.curiosone.core.nlp;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

/**
 * Provides utility methos to perform basic Natural Language Process tasks.
 */
public class LangUtils {

  /**
   * Stores all supported verbs abbreviations in the expandVerbs method.
   */
  private static final String[] SHORTS = {"'m", "'s", "'re", "'ve", "'ll",
      "won't", "n't"};

  /**
   * Stores all the expanded forms for the supported contracted verbs by
   * expandVerbs method.
   */
  private static final String[] LONGS = {" am", " is", " are", " have", " will",
      "will not", " not"};

  /**
   * Splits a text in sentences by punctuation.
   * @param str The original text to be splitted into sentences.
   * @return a list of splitted sentences.
   */
  public static List<String> splitByPuntaction(String str) {
    StringBuffer buff = new StringBuffer();
    ArrayList<String> l = new ArrayList<>();

    boolean email = false;
    boolean uri = false;

    for (int i = 0; i < str.length(); i++) {
      char c = str.charAt(i);

      // Ignore puntaction and spacing at the begining of a phrase.
      if (buff.length() == 0 && (c == '!' || c == '?' || c == '.')) {
        continue;
      }
      if (c == ' ') {
        uri = false;
        email = false;
      }
      buff.append(c);
      // Ignore puntaction inside URIs and inside emails
      if ((email || uri) && (c == '!' || c == '?' || c == '.')) {
        continue;
      }
      if (Character.isLetter(c)) {
        continue;
      }

      // Look ahead for @
      int j = i;
      while (++j < str.length()) {
        if (str.charAt(j) == ' ') {
          break;
        }
        if (str.charAt(j) == '@') {
          email = true;
          break;
        }
      }
      if (email) {
        continue;
      }

      // Look behind for ://
      int len = 0;
      int k = i;
      while (--k >= 0) {
        if (str.charAt(k) == ' ') {
          break;
        }
        if (str.charAt(k) == '/') {
          if (len <= 1) {
            len++;
          } else {
            len = 0;
          }
        } else if (str.charAt(k) == ':') {
          if (len == 2) {
            uri = true;
            break;
          }
        }
      }
      if (uri) {
        continue;
      }

      char p = 0;
      char n = 0;
      if (i + 1 < str.length()) {
        n = str.charAt(i + 1);
      }
      if (i - 1 >= 0) {
        p = str.charAt(i - 1);
      }
      if (c == '?'
          || c == '!'
          || c == '.' && !Character.isDigit(p) && !Character.isDigit(n)) {
        l.add(buff.toString());
        buff = new StringBuffer();
      }
    }
    if (buff.length() > 0) {
      buff.append('.');
      l.add(buff.toString());
    }
    return l;
  }

  /**
   * Removes duplicated spaces from a String.
   * @param str The string with duplicated spaces.
   * @return the original string without double spaces.
   */
  public static String removeDuplicatedSpaces(String str) {
    return StringUtils.normalizeSpace(str);
  }

  /**
   * Expands all the contracted form verbs in a sentence.
   * Note: Works only with lowercased Strings.
   * Note: Saxon Genitive abbreviations could wrongly be treated as "is".
   * @param contracted the phrase to work with
   * @return a new String, containing the old phrase with all verbs expanded
   */
  public static String expandVerbs(String contracted) {
    return StringUtils.replaceEachRepeatedly(contracted, SHORTS, LONGS);
  }

  /**
   * removeNonAlphaNumeric description.
   * @param str [description]
   * @return [description]
   */
  public static String removeNonAlphaNumeric(String str) {
    return str.replaceAll("[^A-Za-z0-9 ]", "");
  }
}

@@ -245,16 +245,181 @@
 tils %7B%0A%0A
+  /**%0A   * Stores the regex used to remove all non-alphanumeric characters from a String.%0A   */%0A  private static final String REGEX_NON_ALPHANUM = %22%5B%5EA-Za-z0-9 %5D%22;%0A%0A
   /**%0A  
@@ -462,18 +462,18 @@
 iations 
-in
+by
  the exp
@@ -672,21 +672,16 @@
 verbs by
-%0A   *
  expandV
@@ -3696,99 +3696,227 @@
   * 
-r
+R
 emove
-NonA
+s non-a
 lpha
-N
+n
 umeric 
-description.%0A   * @param str %5Bdescription%5D%0A   * @return %5Bdescription%5D
+characters from the given String.%0A   * @param str the String to remove non-alphanumeric characters from%0A   * @return a new String containing the result of the non-alphanumeric characters removal
 %0A   
@@ -4003,31 +4003,34 @@
 laceAll(
-%22%5B%5EA-Za-z0-9 %5D%22
+REGEX_NON_ALPHANUM
 , %22%22);%0A 

improve LangUtils javadoc and codestyle