package etomica;

import etomica.integrator.Integrator;
import etomica.normalmode.NormalModeAnalysisDisplay2D;
import etomica.normalmode.NormalModeAnalysisDisplay3D;
import etomica.simulation.Simulation;
import etomica.space.Space;
import etomica.space3d.Space3D;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.TestReporter;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static etomica.TestSimConstructors.SCAN;

public class TestSimShortRuns {
    private static final ExecutorService exec = Executors.newSingleThreadExecutor();

    static List<Arguments> getIntegrators() throws IllegalAccessException, InstantiationException, InvocationTargetException {
        // This beautiful method will search through constructible simulations looking for ones
        // with one and only one field of type Integrator (getIntegrator isn't reliable, and with
        // more than one we don't know which one to use), instantiate the simulations, and return the integrators.
        List<Class<?>> classes =  SCAN.classNamesToClassRefs(SCAN.getNamesOfSubclassesOf(Simulation.class));
        List<Arguments> args = new ArrayList<>();

        for (Class<?> cl : classes) {
            Field[] fields = cl.getDeclaredFields();
            List<Field> integratorFields = Arrays.stream(fields)
                    .filter(f -> Integrator.class.isAssignableFrom(f.getType()))
                    .collect(Collectors.toList());

            if (integratorFields.size() == 1) {
                Simulation sim = null;
                try {
                    sim = (Simulation) cl.getConstructor().newInstance();
                } catch (NoSuchMethodException e) {
                    try {
                        sim = (Simulation) cl.getConstructor(Space.class).newInstance(Space3D.getInstance());
                    } catch (NoSuchMethodException e1) {
                        continue;
                    }
                }

                integratorFields.get(0).setAccessible(true);
                args.add(Arguments.of(cl, (Integrator)integratorFields.get(0).get(sim)));
            }
        }

        System.out.println(args);
        return args;
    }

    @ParameterizedTest
    @MethodSource("getIntegrators")
    void testShortRuns(Class<?> simClass, Integrator simIntegrator, TestReporter reporter) {
        Assertions.assertDoesNotThrow(() -> {
            simIntegrator.reset();
            Future future = exec.submit(() -> {
                while (!Thread.interrupted()) {
                    simIntegrator.doStep();
                }
            });
            Thread.sleep(400);
            reporter.publishEntry(simClass + " steps", Long.toString(simIntegrator.getStepCount()));
            future.cancel(true);
        });

    }
}

@@ -45,24 +45,131 @@
 Integrator;%0A
+import etomica.modules.osmosis.OsmosisSim;%0Aimport etomica.modules.reactionequilibrium.ReactionEquilibrium;%0A
 import etomi
@@ -211,16 +211,16 @@
 play2D;%0A
-
 import e
@@ -792,65 +792,9 @@
 til.
-ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.List
+*
 ;%0Aim
@@ -1143,24 +1143,430 @@
 xecutor();%0A%0A
+    /**%0A     * Sim classes that are excluded for various reasons causing them not to work with the reflection hacks here.%0A     * Currently these just don't initialize box coordinates in the constructor causing a ConfigurationOverlapException%0A     */%0A    private static final Set%3CClass%3C?%3E%3E EXCLUDED = new HashSet%3C%3E(Arrays.asList(%0A            OsmosisSim.class,%0A            ReactionEquilibrium.class%0A    ));%0A%0A
     static L
@@ -2145,24 +2145,24 @@
 yList%3C%3E();%0A%0A
-
         for 
@@ -2183,24 +2183,106 @@
  classes) %7B%0A
+            if (EXCLUDED.contains(cl)) %7B%0A                continue;%0A            %7D%0A%0A
             

Exclude classes which don't work for known reasons from ShortRuns test