package jetbrains.mps.lang.test.runtime;

/*Generated by MPS */

import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
import java.lang.reflect.Method;
import org.junit.jupiter.api.extension.ExtensionContext;
import java.util.concurrent.atomic.AtomicReference;
import jetbrains.mps.ide.ThreadUtils;

/**
 * An extension to run test method as a command.
 */
public class ExecuteCommandExtension implements InvocationInterceptor {

  private final BaseTransformationTest myOwner;

  public ExecuteCommandExtension(BaseTransformationTest owner) {
    this.myOwner = owner;
  }

  @Override
  public void interceptTestMethod(final InvocationInterceptor.Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {

    final AtomicReference<Throwable> throwable = new AtomicReference<Throwable>();
    final Runnable proceed = () -> {
      try {
        invocation.proceed();

      } catch (Throwable e) {
        throwable.set(e);
      }
    };

    ThreadUtils.runInUIThreadAndWait(() -> myOwner.getProject().getModelAccess().executeCommand(proceed));

    Throwable t = throwable.get();
    if (t != null) {
      throw t;
    }
  }
}
