package labs.multiset_f25;

import java.util.function.Consumer;

/**
 * Driver class designed to illustrate a scenario where the CounterMultiset has a significant
 * advantage over the ArrayMultiset and vice versa.
 *
 * @author CS 240 Instructors and ???
 * @version ??
 *
 */
public class WorkloadDriver {

  /**
   * The main method creates an ArrayMultiset and a CounterMultiset and passes them to a method
   * that will perform the same sequence of observations on each and time the results.
   *
   * @param args Not used
   */
  public static void main(String[] args) {

    ArrayMultiset<Integer> arraySet = new ArrayMultiset<>(1000000);
    CounterMultiset<Integer> counterSet = new CounterMultiset<>(10000000);

    System.out.println("Timing ArrayMultiset with counterFriendlyOperations (Should be slow!)");
    performTiming((set) -> counterFriendlyOperations(set), arraySet);

    System.out.println("Timing CounterMultiset with counterFriendlyOperations (Should be fast!):");
    performTiming((set) -> counterFriendlyOperations(set), counterSet);

    arraySet = new ArrayMultiset<>(1000000);
    counterSet = new CounterMultiset<>(1000000);

    System.out.println("Timing ArrayMultiset with arrayFriendlyOperations (Should be fast!)");
    performTiming((set) -> arrayFriendlyOperations(set), arraySet);

    System.out.println("Timing CounterMultiset with arrayFriendlyOperations (Should be slow!):");
    performTiming((set) -> arrayFriendlyOperations(set), counterSet);
  }

  /**
   * Run the provided function and print timing information.
   *
   * @param consumer The function to time. Expects a Multiset.
   * @param set An empty Multiset object (either ArrayMultiset or CounterMultiset)
   */
  public static void performTiming(Consumer<Multiset<Integer>> consumer, Multiset<Integer> set) {
    long start = System.currentTimeMillis();
    consumer.accept(set);
    double elapsed = (System.currentTimeMillis() - start) / 1000.0;
    System.out.println("Done. " + elapsed + " (s)\n");
  }

  /**
   * Perform a set of operations that will take longer when executed with an ArrayMultiset than
   * with a CounterMultiset.
   *
   * <p>
   * For full credit the CounterMultiset should be at least 10 times faster and the entire method
   * should finish within 10 seconds for both collections.
   *
   * @param set An empty Multiset to use for testing
   */
  public static void counterFriendlyOperations(Multiset<Integer> set) {

    // YOUR CODE HERE!

  }

  /**
   * Perform a set of operations that will take longer when executed with a CounterMultiset than
   * with a ArrayMultiset.
   *
   * <p>
   * For full credit the ArrayMultiset should be at least 10 times faster and the entire method
   * should finish within 10 seconds for both collections.
   *
   * @param set An empty Multiset to use for testing
   */
  public static void arrayFriendlyOperations(Multiset<Integer> set) {

    // YOUR CODE HERE!

  }


}
