// Path: java/src/org/drupal/project/computing/exception/DSiteException.java
// public class DSiteException extends Exception {
//     public DSiteException() {
//         super();
//     }
// 
//     public DSiteException(String s) {
//         super(s);
//     }
// 
//     public DSiteException(String s, Throwable throwable) {
//         super(s, throwable);
//     }
// 
//     public DSiteException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     /**
//      * The error code is arbitrary by the caller which sets it.
//      */
//     private int errorCode = 0;
// 
//     public int getErrorCode() {
//         return errorCode;
//     }
// 
//     public void setErrorCode(int errorCode) {
//         this.errorCode = errorCode;
//     }
// 
// }
// 
// Path: java/src/org/drupal/project/computing/exception/DSystemExecutionException.java
// public class DSystemExecutionException extends Exception {
//     public DSystemExecutionException() {
//     }
// 
//     public DSystemExecutionException(String s) {
//         super(s);
//     }
// 
//     public DSystemExecutionException(String s, Throwable throwable) {
//         super(s, throwable);
//     }
// 
//     public DSystemExecutionException(Throwable throwable) {
//         super(throwable);
//     }
// }


import org.apache.commons.exec.CommandLine;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.drupal.project.computing.exception.DSiteException;
import org.drupal.project.computing.exception.DSystemExecutionException;
import javax.script.Bindings;
import javax.script.SimpleBindings;
import java.util.logging.Logger;
package org.drupal.project.computing;



/**
 * This is the utility class to run drush command. You need to specify "dcomp.drush.command" (default "drush") and
 * "dcomp.drush.site" (default "@self") to be able to access Drush. This class interact with Drupal Computing drush
 * "computing-call" and "computing-eval" to execute any Drupal functions.
 */
public class DDrush {

    private String drushCommand;
    private String drushSiteAlias;

    private Logger logger = DUtils.getInstance().getPackageLogger();

    //private Boolean computingEnabled;

    /**
     * This is the only initialization code. Need to specify drush command and siteAlias.
     *
     * @param drushCommand drush executable command
     * @param drushSiteAlias drush site alias
     */
    public DDrush(String drushCommand, String drushSiteAlias) {
        assert StringUtils.isNotBlank(drushCommand) && StringUtils.isNotBlank(drushSiteAlias);
        // TODO: check "drush cc" and existence of computing module.
        this.drushCommand = drushCommand;
        this.drushSiteAlias = drushSiteAlias;
    }

    /**
     * Create a DDrush object using settings from config.properties.
     *
     * @return the DDrush object.
     */
    public static DDrush loadDefault() {
        // might need to check validity.
        DConfig config = DConfig.loadDefault();
        return new DDrush(config.getDrushCommand(), config.getDrushSiteAlias());
    }


    /**
     * Execute Drush command, and returns STDOUT results.
     * attention: here we use shell stdout to output results, which is problematic.
     *
     * possible problems are:
     * 1) security concerns, where confidential info might get printed
     * 2) encoding/decoding characters to byte streams, especially with non-english languages and serializd strings.
     * 3) escaping problems
     * 4) output might get messed up with other sub-processes.
     *
     * some other IPC approaches: 1) Apache Camel, 2) /tmp files, 3) message queue
     * however, STDOUT is the simplest approach for now.
     *
     * @param command The drush command to execute, ignoring drush binary and site alias.
     * @param input Input stream, could be null.
     * @return STDOUT results.
     * @throws org.drupal.project.computing.exception.DSiteException
     */
// Path: java/src/org/drupal/project/computing/exception/DSiteException.java
// public class DSiteException extends Exception {
//     public DSiteException() {
//         super();
//     }
// 
//     public DSiteException(String s) {
//         super(s);
//     }
// 
//     public DSiteException(String s, Throwable throwable) {
//         super(s, throwable);
//     }
// 
//     public DSiteException(Throwable throwable) {
//         super(throwable);
//     }
// 
//     /**
//      * The error code is arbitrary by the caller which sets it.
//      */
//     private int errorCode = 0;
// 
//     public int getErrorCode() {
//         return errorCode;
//     }
// 
//     public void setErrorCode(int errorCode) {
//         this.errorCode = errorCode;
//     }
// 
// }
// 
// Path: java/src/org/drupal/project/computing/exception/DSystemExecutionException.java
// public class DSystemExecutionException extends Exception {
//     public DSystemExecutionException() {
//     }
// 
//     public DSystemExecutionException(String s) {
//         super(s);
//     }
// 
//     public DSystemExecutionException(String s, Throwable throwable) {
//         super(s, throwable);
//     }
// 
//     public DSystemExecutionException(Throwable throwable) {
//         super(throwable);
//     }
// }


// Path: java/src/org/drupal/project/computing/DDrush.java
import org.apache.commons.exec.CommandLine;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.drupal.project.computing.exception.DSiteException;
import org.drupal.project.computing.exception.DSystemExecutionException;
import javax.script.Bindings;
import javax.script.SimpleBindings;
import java.util.logging.Logger;

package org.drupal.project.computing;



/**
 * This is the utility class to run drush command. You need to specify "dcomp.drush.command" (default "drush") and
 * "dcomp.drush.site" (default "@self") to be able to access Drush. This class interact with Drupal Computing drush
 * "computing-call" and "computing-eval" to execute any Drupal functions.
 */
public class DDrush {

    private String drushCommand;
    private String drushSiteAlias;

    private Logger logger = DUtils.getInstance().getPackageLogger();

    //private Boolean computingEnabled;

    /**
     * This is the only initialization code. Need to specify drush command and siteAlias.
     *
     * @param drushCommand drush executable command
     * @param drushSiteAlias drush site alias
     */
    public DDrush(String drushCommand, String drushSiteAlias) {
        assert StringUtils.isNotBlank(drushCommand) && StringUtils.isNotBlank(drushSiteAlias);
        // TODO: check "drush cc" and existence of computing module.
        this.drushCommand = drushCommand;
        this.drushSiteAlias = drushSiteAlias;
    }

    /**
     * Create a DDrush object using settings from config.properties.
     *
     * @return the DDrush object.
     */
    public static DDrush loadDefault() {
        // might need to check validity.
        DConfig config = DConfig.loadDefault();
        return new DDrush(config.getDrushCommand(), config.getDrushSiteAlias());
    }


    /**
     * Execute Drush command, and returns STDOUT results.
     * attention: here we use shell stdout to output results, which is problematic.
     *
     * possible problems are:
     * 1) security concerns, where confidential info might get printed
     * 2) encoding/decoding characters to byte streams, especially with non-english languages and serializd strings.
     * 3) escaping problems
     * 4) output might get messed up with other sub-processes.
     *
     * some other IPC approaches: 1) Apache Camel, 2) /tmp files, 3) message queue
     * however, STDOUT is the simplest approach for now.
     *
     * @param command The drush command to execute, ignoring drush binary and site alias.
     * @param input Input stream, could be null.
     * @return STDOUT results.
     * @throws org.drupal.project.computing.exception.DSiteException
     */
    public String execute(String[] command, String input) throws DSiteException {