// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/ErlangVersion.java
// public final class ErlangVersion {
//   public static final String V22_3 = "22.3";
//   public static final String V21_3 = "21.3";
//   public static final String V20_3 = "20.3";
//   public static final String V19_3_6_4 = "19.3.6.4";
//   public static final String V19_3 = "19.3";
//   public static final String R16B03 = "r16b03";
//   public static final String R13B03 = "r13b03";
//   public static final String UNKNOWN = null;
// }
// 
// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/bin/ErlangShell.java
// public class ErlangShell {
//   private static final String LOGGER_TEMPLATE = "%s.Process.%s";
// 
//   private static final String UNIX_ERL_COMMAND = "erl";
// 
//   private final EmbeddedRabbitMqConfig config;
// 
//   /**
//    * Generic Constructor.
//    */
//   public ErlangShell(final EmbeddedRabbitMqConfig config) {
//     this.config = config;
// 
//   }
// 
//   /**
//    * @return a String representing the Erlang version, such as {@code "18.2.1"}
//    * @throws ErlangShellException if the Erlang command can't be executed or if it exits unexpectedly.
//    */
//   public String getErlangVersion() throws ErlangShellException {
//     String erlangShell = UNIX_ERL_COMMAND;
// 
//     Logger processOutputLogger = LoggerFactory.getLogger(
//         String.format(LOGGER_TEMPLATE, this.getClass().getName(), erlangShell));
// 
//     Slf4jStream stream = Slf4jStream.of(processOutputLogger);
// 
//     final ProcessExecutor processExecutor = config.getProcessExecutorFactory().createInstance()
//         .command(erlangShell, "-noshell", "-eval", "erlang:display(erlang:system_info(otp_release)), halt().")
//         .timeout(config.getErlangCheckTimeoutInMillis(), TimeUnit.MILLISECONDS)
//         .redirectError(stream.as(Level.WARN))
//         .destroyOnExit()
//         .readOutput(true);
// 
//     try {
//       ProcessResult processResult = processExecutor.execute();
//       int exitValue = processResult.getExitValue();
//       if (exitValue == 0) {
//         return processResult.outputUTF8().trim().replaceAll("[\"\\\\n]", ""); // "18.2.1\n" -> "18.2.1"
//       } else {
//         throw new ErlangShellException("Erlang exited with status " + exitValue);
//       }
//     } catch (IOException | InterruptedException | TimeoutException e) {
//       throw new ErlangShellException("Exception executing Erlang shell command", e);
//     }
//   }
// }
// 
// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/bin/ErlangShellException.java
// public class ErlangShellException extends Exception {
//   public ErlangShellException(String message) {
//     super(message);
//   }
// 
//   public ErlangShellException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }


import io.arivera.oss.embedded.rabbitmq.ErlangVersion;
import io.arivera.oss.embedded.rabbitmq.bin.ErlangShell;
import io.arivera.oss.embedded.rabbitmq.bin.ErlangShellException;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
    ErlangVersionChecker checker = new ErlangVersionChecker(RandomStringUtils.random(3), shell);
    checker.check();
  }

  @Test
  public void noRequiredVersion() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.2.1");

    String minErlangVersion = null;
    ErlangVersionChecker checker = new ErlangVersionChecker(minErlangVersion, shell);
    checker.check();
  }

  @Test
  public void versionCheckPasses() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.1");

    String minErlangVersion = "R14B01-3";
    ErlangVersionChecker checker = new ErlangVersionChecker(minErlangVersion, shell);
    checker.check();
  }

  @Test
  public void versionCheckPasses2() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.1.0");
    new ErlangVersionChecker("18.0.1", shell).check();
  }

  @Test(expected = ErlangVersionException.class)
  public void versionCheckFails() throws ErlangShellException {
// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/ErlangVersion.java
// public final class ErlangVersion {
//   public static final String V22_3 = "22.3";
//   public static final String V21_3 = "21.3";
//   public static final String V20_3 = "20.3";
//   public static final String V19_3_6_4 = "19.3.6.4";
//   public static final String V19_3 = "19.3";
//   public static final String R16B03 = "r16b03";
//   public static final String R13B03 = "r13b03";
//   public static final String UNKNOWN = null;
// }
// 
// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/bin/ErlangShell.java
// public class ErlangShell {
//   private static final String LOGGER_TEMPLATE = "%s.Process.%s";
// 
//   private static final String UNIX_ERL_COMMAND = "erl";
// 
//   private final EmbeddedRabbitMqConfig config;
// 
//   /**
//    * Generic Constructor.
//    */
//   public ErlangShell(final EmbeddedRabbitMqConfig config) {
//     this.config = config;
// 
//   }
// 
//   /**
//    * @return a String representing the Erlang version, such as {@code "18.2.1"}
//    * @throws ErlangShellException if the Erlang command can't be executed or if it exits unexpectedly.
//    */
//   public String getErlangVersion() throws ErlangShellException {
//     String erlangShell = UNIX_ERL_COMMAND;
// 
//     Logger processOutputLogger = LoggerFactory.getLogger(
//         String.format(LOGGER_TEMPLATE, this.getClass().getName(), erlangShell));
// 
//     Slf4jStream stream = Slf4jStream.of(processOutputLogger);
// 
//     final ProcessExecutor processExecutor = config.getProcessExecutorFactory().createInstance()
//         .command(erlangShell, "-noshell", "-eval", "erlang:display(erlang:system_info(otp_release)), halt().")
//         .timeout(config.getErlangCheckTimeoutInMillis(), TimeUnit.MILLISECONDS)
//         .redirectError(stream.as(Level.WARN))
//         .destroyOnExit()
//         .readOutput(true);
// 
//     try {
//       ProcessResult processResult = processExecutor.execute();
//       int exitValue = processResult.getExitValue();
//       if (exitValue == 0) {
//         return processResult.outputUTF8().trim().replaceAll("[\"\\\\n]", ""); // "18.2.1\n" -> "18.2.1"
//       } else {
//         throw new ErlangShellException("Erlang exited with status " + exitValue);
//       }
//     } catch (IOException | InterruptedException | TimeoutException e) {
//       throw new ErlangShellException("Exception executing Erlang shell command", e);
//     }
//   }
// }
// 
// Path: src/main/java/io/arivera/oss/embedded/rabbitmq/bin/ErlangShellException.java
// public class ErlangShellException extends Exception {
//   public ErlangShellException(String message) {
//     super(message);
//   }
// 
//   public ErlangShellException(String message, Throwable cause) {
//     super(message, cause);
//   }
// }


// Path: src/test/java/io/arivera/oss/embedded/rabbitmq/helpers/ErlangVersionCheckerTest.java
import io.arivera.oss.embedded.rabbitmq.ErlangVersion;
import io.arivera.oss.embedded.rabbitmq.bin.ErlangShell;
import io.arivera.oss.embedded.rabbitmq.bin.ErlangShellException;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;

    ErlangVersionChecker checker = new ErlangVersionChecker(RandomStringUtils.random(3), shell);
    checker.check();
  }

  @Test
  public void noRequiredVersion() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.2.1");

    String minErlangVersion = null;
    ErlangVersionChecker checker = new ErlangVersionChecker(minErlangVersion, shell);
    checker.check();
  }

  @Test
  public void versionCheckPasses() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.1");

    String minErlangVersion = "R14B01-3";
    ErlangVersionChecker checker = new ErlangVersionChecker(minErlangVersion, shell);
    checker.check();
  }

  @Test
  public void versionCheckPasses2() throws ErlangShellException {
    when(shell.getErlangVersion()).thenReturn("18.1.0");
    new ErlangVersionChecker("18.0.1", shell).check();
  }

  @Test(expected = ErlangVersionException.class)
  public void versionCheckFails() throws ErlangShellException {
      when(shell.getErlangVersion()).thenReturn("21.0.1");