package com.example.appactionvisualizer.utils;

import android.content.Context;

import com.example.appactionvisualizer.R;

import static com.example.appactionvisualizer.constants.Constant.URL_PARAMETER_INDICATOR;

public class StringUtils {

  /**
   * @param text text to be matched
   * @param pattern match pattern
   * @return Levenshtein distance between two string
   */
  public static int distance(String text, String pattern) {
    int textLength = text.length();
    int patternLength = pattern.length();
    if(textLength <= patternLength - 2) {
      return patternLength;
    }
    // if one of the strings is empty
    if (textLength * patternLength == 0)
      return textLength + patternLength;
    int [][] dp = new int[textLength + 1][patternLength + 1];

    // init boundaries
    for (int idx = 0; idx < textLength + 1; idx++) {
      dp[idx][0] = idx;
    }
    for (int idx = 0; idx < patternLength + 1; idx++) {
      dp[0][idx] = idx;
    }

    // DP compute
    for (int idx1 = 1; idx1 < textLength + 1; idx1++) {
      for (int idx2 = 1; idx2 < patternLength + 1; idx2++) {
        int left = dp[idx1 - 1][idx2] + 1;
        int down = dp[idx1][idx2 - 1] + 1;
        int left_down = dp[idx1 - 1][idx2 - 1];
        if (text.charAt(idx1 - 1) != pattern.charAt(idx2 - 1))
          left_down += 1;
        dp[idx1][idx2] = Math.min(left, Math.min(down, left_down));
      }
    }
    return dp[textLength][patternLength];
  }

  /**
   * @param tobeMatched actions array
   * @param inputWords input words array
   * @return a matched "score" by computing matched strings between two arrays
   */
  public static int matchScore(String[] tobeMatched, String[] inputWords) {
    if(tobeMatched.length > inputWords.length) {
      return matchScore(inputWords, tobeMatched);
    }
    int maxScore = 0;
    int len = tobeMatched.length;
    for(int startIdx = 0; startIdx <= inputWords.length - len; ++startIdx) {
      int score = 0;
      for(int patternIdx = 0; patternIdx < len; ++patternIdx) {
        score += getScore(inputWords[startIdx + patternIdx], tobeMatched[patternIdx]);
      }
      maxScore = Math.max(maxScore, score);
    }
    return maxScore;
  }

  /**
   * @param text word to be matched
   * @param pattern pattern of the word
   * @return a final score, which is length - Levenshtein Distance between two words
   */
  public static int getScore(String text, String pattern) {
    if(pattern.startsWith(text)) {
      return pattern.length();
    }
    return 0;
//    int score = Math.max(text.length(), pattern.length()) - distance(text, pattern);
//    int minSize = Math.min(text.length(), pattern.length());
//    // Can only tolerate with two mismatch characters.
//    return score >= (pattern.length() - 1) ? score : 0;
  }

  /**
   * replace parameter with input from user to construct the url e.g.:
   * https://example.com/test?utm_campaign=appactions{#foo} ==>
   * https://example.com/test?utm_campaign=appactions#foo=123
   * myapp://example/{foo} ==> myapp://example/123
   *
   * @param identifier
   */
  public static String replaceSingleParameter(
      Context context, String urlTemplate, String key, String identifier) {
    if (key == null) return "";
    int firstPartIdx = urlTemplate.indexOf(URL_PARAMETER_INDICATOR);
    int secondPartIdx = urlTemplate.indexOf("}");
    String curUrl = urlTemplate.substring(0, firstPartIdx);
    if (Character.isAlphabetic(urlTemplate.charAt(firstPartIdx + 1))) {
      curUrl += identifier;
    } else {
      curUrl +=
          urlTemplate.charAt(firstPartIdx + 1) + context.getString(R.string.url_parameter, key, identifier);
    }
    curUrl += urlTemplate.substring(secondPartIdx + 1);
    return curUrl;
  }
}

@@ -240,1220 +240,8 @@
  %7B%0A%0A
-  /**%0A   * @param text text to be matched%0A   * @param pattern match pattern%0A   * @return Levenshtein distance between two string%0A   */%0A  public static int distance(String text, String pattern) %7B%0A    int textLength = text.length();%0A    int patternLength = pattern.length();%0A    if(textLength %3C= patternLength - 2) %7B%0A      return patternLength;%0A    %7D%0A    // if one of the strings is empty%0A    if (textLength * patternLength == 0)%0A      return textLength + patternLength;%0A    int %5B%5D%5B%5D dp = new int%5BtextLength + 1%5D%5BpatternLength + 1%5D;%0A%0A    // init boundaries%0A    for (int idx = 0; idx %3C textLength + 1; idx++) %7B%0A      dp%5Bidx%5D%5B0%5D = idx;%0A    %7D%0A    for (int idx = 0; idx %3C patternLength + 1; idx++) %7B%0A      dp%5B0%5D%5Bidx%5D = idx;%0A    %7D%0A%0A    // DP compute%0A    for (int idx1 = 1; idx1 %3C textLength + 1; idx1++) %7B%0A      for (int idx2 = 1; idx2 %3C patternLength + 1; idx2++) %7B%0A        int left = dp%5Bidx1 - 1%5D%5Bidx2%5D + 1;%0A        int down = dp%5Bidx1%5D%5Bidx2 - 1%5D + 1;%0A        int left_down = dp%5Bidx1 - 1%5D%5Bidx2 - 1%5D;%0A        if (text.charAt(idx1 - 1) != pattern.charAt(idx2 - 1))%0A          left_down += 1;%0A        dp%5Bidx1%5D%5Bidx2%5D = Math.min(left, Math.min(down, left_down));%0A      %7D%0A    %7D%0A    return dp%5BtextLength%5D%5BpatternLength%5D;%0A  %7D%0A%0A
   /*
@@ -488,16 +488,17 @@
 %7B%0A    if
+ 
 (tobeMat
@@ -647,24 +647,25 @@
 gth;%0A    for
+ 
 (int startId
@@ -752,16 +752,17 @@
      for
+ 
 (int pat
@@ -1102,55 +1102,28 @@
  is 
-length - Levenshtein Distance between two words
+the pattern's length
 %0A   
@@ -1191,16 +1191,17 @@
 %7B%0A    if
+ 
 (pattern
@@ -1276,273 +1276,8 @@
  0;%0A
-//    int score = Math.max(text.length(), pattern.length()) - distance(text, pattern);%0A//    int minSize = Math.min(text.length(), pattern.length());%0A//    // Can only tolerate with two mismatch characters.%0A//    return score %3E= (pattern.length() - 1) ? score : 0;%0A
   %7D%0A
@@ -1479,21 +1479,16 @@
 #foo=123
-%0A   *
  myapp:/
@@ -1505,16 +1505,21 @@
 foo%7D ==%3E
+%0A   *
  myapp:/
@@ -2074,16 +2074,30 @@
 Idx + 1)
+%0A             
  + conte

delete redundant code