/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package geode.kafka;

import java.io.File;
import java.io.IOException;

public class JavaProcess {

  public Process process;
  Class classWithMain;

  public JavaProcess(Class classWithmain) {
    this.classWithMain = classWithmain;
  }

  public void exec(String... args) throws IOException, InterruptedException {
    String java =
        System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
    String classpath = System.getProperty("java.class.path");
    String className = classWithMain.getName();

    ProcessBuilder builder = new ProcessBuilder(
        java, "-cp", classpath, className, convertArgsToString(args));

    process = builder.inheritIO().start();
  }

  private String convertArgsToString(String... args) {
    String string = "";
    for (String arg : args) {
      string += arg;
    }
    return string;
  }

  public void waitFor() throws InterruptedException {
    process.waitFor();
  }

  public void destroy() {
    process.destroy();
  }



}
