/**
 *  Copyright (C) 2009 Progress Software, Inc. All rights reserved.
 *  http://fusesource.com
 *
 *  Licensed 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.
 */
import java.util.concurrent.TimeoutException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static org.fusesource.meshkeeper.Expression.*;
import org.fusesource.meshkeeper.HostProperties;
import org.fusesource.meshkeeper.LaunchDescription;
import org.fusesource.meshkeeper.MavenTestSupport;
import org.fusesource.meshkeeper.MeshKeeper;
import org.fusesource.meshkeeper.MeshKeeper.Launcher;
import org.fusesource.meshkeeper.MeshKeeperFactory;
import org.fusesource.meshkeeper.MeshProcess;
import org.fusesource.meshkeeper.util.DefaultProcessListener;

import junit.framework.TestCase;

/**
 * This TestCase shows you how you can use MeshKeeper to launch remote
 * processes in your test case.
 *
 */
public class LauncherTest extends TestCase {

    MeshKeeper meshKeeper;

    protected void setUp() throws Exception {
        //Use MavenTestSupport to create MeshKeeper under target directory:
        meshKeeper = MavenTestSupport.createMeshKeeper("LauncherTest");
    }

    protected void tearDown() throws Exception {
        if (meshKeeper != null) {
            meshKeeper.destroy();
            meshKeeper = null;
        }
    }

    private String getAgent() throws InterruptedException, TimeoutException
    {
        meshKeeper.launcher().waitForAvailableAgents(5000);
        return meshKeeper.launcher().getAvailableAgents()[0].getAgentId();
    }

    public void testDataOutput() throws Exception {

        // Process launching is main focused around the Launcher interface
        Launcher launcher = meshKeeper.launcher();

        // Lets get an agent to launch on...
        launcher.waitForAvailableAgents(5000);
        HostProperties host = launcher.getAvailableAgents()[0];

        System.out.println("Launching on: "+host.getExternalHostName());

        // Setup a simple remote command to execute.. we are just going to do an echo of the OS
        LaunchDescription ld = new LaunchDescription();
        ld.add("echo");
        ld.add("The remote OS is a: ");
        ld.add(property("os.name"));

        final CountDownLatch done = new CountDownLatch(1);
        final AtomicInteger exitCode = new AtomicInteger();

        // All process output will be delivered to this listener..
        DefaultProcessListener listener = new DefaultProcessListener("remote process") {
            @Override
            public void onProcessExit(int code) {
                exitCode.set(code);
                done.countDown();
            }
        };

        MeshProcess process = launcher.launchProcess(host.getAgentId(), ld, listener);

        assertTrue(done.await(10, TimeUnit.SECONDS));
        assertEquals(0, exitCode.get());

    }


}

@@ -897,16 +897,62 @@
 ssion.*;
+%0A%0Aimport org.fusesource.meshkeeper.Expression;
 %0Aimport 
@@ -1464,19 +1464,16 @@
 h remote
-%0A *
  process
@@ -1474,16 +1474,19 @@
 rocesses
+%0A *
  in your
@@ -1499,16 +1499,17 @@
 case.%0A *
+ 
 %0A */%0Apub
@@ -1961,14 +1961,22 @@
 ate 
-String
+HostProperties
  get
@@ -2028,20 +2028,16 @@
 xception
-%0A   
  %7B%0A     
@@ -2151,29 +2151,16 @@
 nts()%5B0%5D
-.getAgentId()
 ;%0A    %7D%0A
@@ -2352,154 +2352,40 @@
     
-// Lets get an agent to launch on...%0A        launcher.waitForAvailableAgents(5000);%0A        HostProperties host = launcher.getAvailable
+HostProperties host = get
 Agent
-s
 ()
-%5B0%5D
 ;%0A%0A 
@@ -2430,9 +2430,11 @@
 n: %22
-+
+ + 
 host
@@ -2471,152 +2471,389 @@
     
-// Setup a simple remote command to execute.. we are just going to do an echo of the OS%0A        LaunchDescription ld = new LaunchDescription();%0A
+boolean windows = host.getSystemProperties().get(%22os.name%22).toString().toLowerCase().contains(%22windows%22);%0A%0A        // Setup a simple remote command to execute.. we are just going to do a simple echo %0A        // of Hello World from the host machines timezone.%0A        LaunchDescription ld = new LaunchDescription();%0A        //For windows start cmd shell:%0A        if (windows) %7B%0A    
     
@@ -2864,20 +2864,19 @@
 ld.add(%22
-echo
+cmd
 %22);%0A    
@@ -2879,24 +2879,28 @@
         
+ 
+   
 ld.add(%22
 The remo
@@ -2895,65 +2895,293 @@
 dd(%22
-The remote OS is a: %22);%0A        ld.add(property(%22os.name%22
+/c%22);%0A        %7D%0A        ld.add(%22echo%22);%0A        //Note the use of Expressions' append', 'string' and 'property' used to build the command.%0A        //Here the 'property' is evaluated from the host's launcher:%0A        ld.add(append(string(%22Hello World From: %22), property(%22user.timezone%22)
 ));%0A
@@ -3712,16 +3712,24 @@
 tener);%0A
+        
 %0A       
@@ -3820,15 +3820,13 @@
 ));%0A
-%0A
     %7D%0A%0A
-%0A
 %7D%0A

Fixing a problem launching example A on windows 2003