/**
 * Logback: the reliable, generic, fast and flexible logging framework.
 * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
 *
 * This program and the accompanying materials are dual-licensed under
 * either the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation
 *
 *   or (per the licensee's choosing)
 *
 * under the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation.
 */
package ch.qos.logback.core.util;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Static utility methods for working with collections of strings.
 *
 * @author Carl Harris
 */
public class StringCollectionUtil {

  /**
   * Retains all values in the subject collection that are matched by
   * at least one of a collection of regular expressions.
   * <p>
   * This method is a convenience overload for
   * {@link #retainMatching(Collection, Collection)}.
   *   
   * @param values subject value collection 
   * @param patterns patterns to match
   */
  @SuppressWarnings("unchecked")
  public static void retainMatching(Collection<String> values, 
      String... patterns) {
    retainMatching(values, Arrays.asList(patterns));
  }

  /**
   * Retains all values in the subject collection that are matched by
   * at least one of a collection of regular expressions.
   * <p>
   * The semantics of this method are conceptually similar to
   * {@link Collection#retainAll(Collection)}, but uses pattern matching
   * instead of exact matching.
   * 
   * @param values subject value collection 
   * @param patterns patterns to match
   */
  public static void retainMatching(Collection<String> values,
      Collection<String> patterns) {
    if (patterns.isEmpty()) return;
    List<String> matches = new ArrayList<String>(values.size());
    for (String p : patterns) {
      Pattern pattern = Pattern.compile(p);
      for (String value : values) {
        if (pattern.matcher(value).matches()) {
          matches.add(value);
        }
      }
    }
    values.retainAll(matches);
  }
  
  /**
   * Removes all values in the subject collection that are matched by
   * at least one of a collection of regular expressions.
   * <p>
   * This method is a convenience overload for
   * {@link #removeMatching(Collection, Collection)}.
   * 
   * @param values subject value collection 
   * @param patterns patterns to match
   */
  @SuppressWarnings("unchecked")
  public static void removeMatching(Collection<String> values, 
      String... patterns) {
    removeMatching(values, Arrays.asList(patterns));
  }

  /**
   * Removes all values in the subject collection that are matched by
   * at least one of a collection of regular expressions.
   * <p>
   * The semantics of this method are conceptually similar to
   * {@link Collection#removeAll(Collection)}, but uses pattern matching
   * instead of exact matching.
   * 
   * @param values subject value collection 
   * @param patterns patterns to match
   */
  public static void removeMatching(Collection<String> values, 
      Collection<String> patterns) {
    List<String> matches = new ArrayList<String>(values.size());
    for (String p : patterns) {
      Pattern pattern = Pattern.compile(p);
      for (String value : values) {
        if (pattern.matcher(value).matches()) {
          matches.add(value);
        }
      }
    }
    values.removeAll(matches);
  }

}
