// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.testFramework;

import com.intellij.util.SmartList;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.lang.CompoundRuntimeException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;

/**
 * Runs all given runnables and throws all the caught exceptions at the end.
 *
 * @author peter
 */
public class RunAll implements Runnable {
  private final List<? extends ThrowableRunnable<?>> myActions;

  @SafeVarargs
  public RunAll(@NotNull ThrowableRunnable<Throwable>... actions) {
    this(ContainerUtil.newArrayList(actions));
  }

  private RunAll(@NotNull List<? extends ThrowableRunnable<?>> actions) {
    myActions = actions;
  }

  @SafeVarargs
  @Contract(pure=true)
  public final RunAll append(@NotNull ThrowableRunnable<Throwable>... actions) {
    return new RunAll(ContainerUtil.concat(myActions, actions.length == 1 ? Collections.singletonList(actions[0]) : ContainerUtil.newArrayList(actions)));
  }

  @Override
  public void run() {
    run(Collections.emptyList());
  }
  public void run(@NotNull List<? extends Throwable> suppressedExceptions) {
    List<Throwable> throwables = collectExceptions();
    throwables.addAll(0, suppressedExceptions);
    CompoundRuntimeException.throwIfNotEmpty(throwables);
  }

  @NotNull
  private List<Throwable> collectExceptions() {
    List<Throwable> errors = new SmartList<>();
    for (ThrowableRunnable<?> action : myActions) {
      try {
        action.run();
      }
      catch (CompoundRuntimeException e) {
        errors.addAll(e.getExceptions());
      }
      catch (Throwable e) {
        errors.add(e);
      }
    }
    return errors;
  }
}

@@ -18,9 +18,9 @@
 -201
-8
+9
  Jet
@@ -207,16 +207,108 @@
 rtList;%0A
+import com.intellij.util.ThrowableConsumer;%0Aimport com.intellij.util.ThrowablePairConsumer;%0A
 import c
@@ -536,16 +536,45 @@
 tNull;%0A%0A
+import java.util.Collection;%0A
 import j
@@ -617,16 +617,38 @@
 il.List;
+%0Aimport java.util.Map;
 %0A%0A/**%0A *
@@ -1123,17 +1123,19 @@
 act(pure
-=
+ = 
 true)%0A  
@@ -1256,16 +1256,23 @@
 .concat(
+%0A      
 myAction
@@ -1273,16 +1273,22 @@
 Actions,
+%0A     
  actions
@@ -1377,16 +1377,21 @@
 actions)
+%0A    
 ));%0A  %7D%0A
@@ -1463,16 +1463,17 @@
 ));%0A  %7D%0A
+%0A
   public
@@ -2087,11 +2087,679 @@
 ors;%0A  %7D
+%0A%0A  @NotNull%0A  public static %3CT, E extends Throwable%3E RunAll runAll(@NotNull Collection%3C? extends T%3E input,%0A                                                       @NotNull ThrowableConsumer%3C? super T, ? extends E%3E action) %7B%0A    return new RunAll(ContainerUtil.map(input, it -%3E (ThrowableRunnable%3CE%3E)() -%3E action.consume(it)));%0A  %7D%0A%0A  @NotNull%0A  public static %3CK, V, E extends Throwable%3E RunAll runAll(@NotNull Map%3C? extends K, ? extends V%3E input,%0A                                                          @NotNull ThrowablePairConsumer%3C? super K, ? super V, ? extends E%3E action) %7B%0A    return runAll(input.entrySet(), e -%3E action.consume(e.getKey(), e.getValue()));%0A  %7D
 %0A%7D%0A

add ability to run action for bunch of different inputs