/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */

package cx2x.translator.common;

import cx2x.translator.language.helper.accelerator.AcceleratorDirective;
import cx2x.translator.language.helper.target.Target;
import xcodeml.util.XmOption;

import java.util.*;

/**
 * This class contains utilities methods that are useful in the whole project.
 * Mostly to implements java 1.8 features that are not present in java 1.7.
 *
 * @author clementval
 */
public class Utility {

  /**
   * Join an array of String elements into a single String.
   *
   * @param delimiter Delimiter to be placed between each element.
   * @param elements  Array of String elements.
   * @return A joined string of all elements separated by the delimiter.
   */
  public static String join(String delimiter, String[] elements) {
    StringBuilder ret = new StringBuilder();
    boolean firstIteration = true;
    for(String s : elements) {
      if(!firstIteration) {
        ret.append(delimiter);
      } else {
        firstIteration = false;
      }
      ret.append(s);
    }
    return ret.toString();
  }

  /**
   * Join a list of String elements into a single String.
   *
   * @param delimiter Delimiter to be placed between each element.
   * @param elements  List of String elements.
   * @param <T>       Type of element in the list.
   * @return A joined string of all elements separated by the delimiter.
   */
  public static <T> String join(String delimiter, List<T> elements) {
    StringBuilder ret = new StringBuilder();
    Iterator<T> it = elements.iterator();
    while(it.hasNext()) {
      ret.append(it.next().toString());
      if(it.hasNext()) {
        ret.append(delimiter);
      }
    }
    return ret.toString();
  }

  /**
   * Print debugging information on the standard output if option is active.
   *
   * @param value Value to be printed.
   */
  public static void debug(String value) {
    if(XmOption.isDebugOutput()) {
      System.out.println(value);
    }
  }

  /**
   * Convert an object back to a List<String>
   *
   * @param rawObject Raw object to be converted.
   * @return A list of string values. If the raw object is null or not an
   * original list of string, the returned list will be empty.
   */
  public static List<String> convertToList(Object rawObject) {
    List<String> strList = new ArrayList<>();
    if(rawObject != null && rawObject instanceof ArrayList) {
      List rawList = (ArrayList) rawObject;
      for(Object object : rawList) {
        strList.add(Objects.toString(object, null));
      }
    }
    return strList;
  }

  /**
   * Check if there is an intersection between the set and the list.
   *
   * @param set  A given set.
   * @param list A given list.
   * @param <T>  Type of the objects in set or list.
   * @return True if there is an intersection. False otherwise.
   */
  public static <T> boolean hasIntersection(Set<T> set, List<T> list) {
    for(T n : set) {
      if(list.contains(n)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Print a string with a specified indentation at the beginning.
   *
   * @param indent Number of spaces to indent.
   * @param value  Text value to be printed.
   */
  public static void printWithIdent(int indent, String value) {
    for(int i = 0; i < indent; ++i) {
      System.out.print(" ");
    }
    System.out.println(value);
  }

  /**
   * Get a formatted suffix for the CLAW module file including the directive
   * and target of the current transformation.
   * .[directive].[target].claw
   *
   * @param target    The current transformation target.
   * @param directive The current accelerator directive used in transformation.
   * @return A formatted string for the CLAW module file name.
   */
  public static String formattedModuleFilePrefix(Target target,
                                                 AcceleratorDirective directive)
  {
    return "." + directive.toString() +
        "." + target.toString() +
        ClawConstant.CLAW_MOD_SUFFIX;
  }

  /**
   * Count the number of occurrences of pattern in source string.
   * @param source  String in which the pattern is search for.
   * @param pattern Pattern to be found.
   * @return Number of occurrences.
   */
  public static int countOccurrences(String source, String pattern) {
    int lastIndex = 0;
    int count = 0;
    while(lastIndex != -1) {
      lastIndex = source.indexOf(pattern, lastIndex);
      if(lastIndex != -1) {
        count++;
        lastIndex += pattern.length();
      }
    }
    return count;
  }


}

@@ -4121,24 +4121,29 @@
 rce string.%0A
+   *%0A
    * @param 
@@ -4193,16 +4193,16 @@
 ch for.%0A
-
    * @pa
@@ -4354,90 +4354,21 @@
     
-int lastIndex = 0;%0A    int count = 0;%0A    while(lastIndex != -1) %7B%0A      lastIndex
+String newStr
  = s
@@ -4377,15 +4377,15 @@
 rce.
-indexOf
+replace
 (pat
@@ -4394,134 +4394,80 @@
 rn, 
-lastIndex);%0A      if(lastIndex != -1) %7B%0A        count++;%0A        lastIndex += pattern.length();%0A      %7D%0A    %7D%0A    return count
+%22%22);%0A    return ((source.length() - newStr.length())) / pattern.length()
 ;%0A  

Simplify occurrence count