/*
 * Copyright © 2010 Red Hat, Inc.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.redhat.rhevm.api.powershell.util;

import java.io.InputStream;
import java.util.Scanner;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PowerShellCmd {
    private static final Log log = LogFactory.getLog(PowerShellCmd.class);

    private String script;

    public PowerShellCmd(String script) {
        this.script = script;
    }

    private String stdout, stderr;

    public int runAndWait(Process p) {
        try {
            p.getOutputStream().write(script.getBytes());
            p.getOutputStream().close();
        } catch (java.io.IOException ex) {
            throw new PowerShellException("Writing to powershell process failed", ex);
        }

        StreamReader stdoutThread = new StreamReader(p.getInputStream());
        StreamReader stderrThread = new StreamReader(p.getErrorStream());

        stdoutThread.start();
        stderrThread.start();

        while (true) {
            try {
                p.waitFor();
                stdoutThread.join();
                stderrThread.join();
                break;
            } catch	(java.lang.InterruptedException ex) {
                /* with waitFor(), this is needed to clear
                 * the interrupted status flag:
                 *   http://bugs.sun.com/view_bug.do?bug_id=6420270
                 */
                Thread.interrupted();
            }
        }

        stdout = stdoutThread.getOutput();
        stderr = stderrThread.getOutput();

        return p.exitValue();
    }

    public int run() {
        log.debug("Running '" + script + "'");

        ProcessBuilder pb = new ProcessBuilder("powershell", "-command", "-");

        Process p;

        try {
            p = pb.start();
        } catch	(java.io.IOException ex) {
            throw new PowerShellException("Launching powershell failed", ex);
        }

        try {
            return runAndWait(p);
        } finally {
            p.destroy();
        }
    }

    public String getStdOut() {
        return this.stdout;
    }

    public String getStdErr() {
        return this.stderr;
    }

    private class StreamReader extends Thread {
        private InputStream is;

        public StreamReader(InputStream is) {
            this.is = is;
        }

        private StringBuilder outputBuffer = new StringBuilder();
        public String getOutput() {
            return outputBuffer.toString();
        }

        @Override
        public void run() {
            try {
                Scanner sc = new Scanner(is);
                while (sc.hasNext()) {
                    outputBuffer.append(sc.nextLine() + "\n");
                }
            } finally {
                try {
                    this.is.close();
                } catch (java.io.IOException ex) {
                    log.error("Exception while closing input stream", ex);
                }
            }
        }
    }

    public static String runCommand(String command) {
        PowerShellCmd cmd = new PowerShellCmd(command);

        int exitstatus = cmd.run();

        if (!cmd.getStdErr().isEmpty()) {
            log.warn(cmd.getStdErr());
        }

        if (exitstatus != 0) {
            throw new PowerShellException("Command '" + command + "' exited with status=" + exitstatus);
        }

        return cmd.getStdOut();
    }
}

@@ -857,16 +857,37 @@
 .util;%0A%0A
+import java.io.File;%0A
 import j
@@ -2369,32 +2369,496 @@
 Value();%0A    %7D%0A%0A
+    /* On Windows 2008 R2, which is always 64-bit, the PowerShell bindings%0A     * are only installed in the  32-bit %22Windows on Windows%22 environment.%0A     */%0A    private static final String SYSWOW64_PATH = %22C:%5C%5CWindows%5C%5CSysWOW64%5C%5CWindowsPowerShell%5C%5Cv1.0%5C%5Cpowershell.exe%22;%0A%0A    private String findPowerShell() %7B%0A        if (new File(SYSWOW64_PATH).exists()) %7B%0A            return SYSWOW64_PATH;%0A        %7D else %7B%0A            return %22powershell.exe%22;%0A        %7D%0A    %7D%0A%0A
     public int r
@@ -2963,20 +2963,24 @@
 der(
-%22p
+findP
 ower
-s
+S
 hell
-%22
+()
 , %22-

Handle running powershell on 2008 R2