package brooklyn.cli;

import brooklyn.rest.BrooklynService;
import brooklyn.rest.core.ApplicationManager;
import com.google.common.collect.Iterables;
import com.yammer.dropwizard.logging.Log;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.net.URL;

import static org.testng.Assert.assertEquals;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

public class ClientTest {

    private final static Log LOG = Log.forClass(ClientTest.class);

    private BrooklynService brooklynServer;
    private ApplicationManager applicationManager;
    private Client brooklynClient;

    private ByteArrayOutputStream outBytes;
    private PrintStream out;
    private ByteArrayOutputStream errBytes;
    private PrintStream err;

    protected String standardOut() {
        return outBytes.toString();
    }

    protected String standardErr() {
        return errBytes.toString();
    }

    @BeforeClass
    public void setUp() throws Exception {
        // Start the REST server
        brooklynServer = BrooklynService.newBrooklynService();

        //TODO Create a temporary file for config.sample.yml, so can run in jenkins?
        //URL configUrl = getClass().getClassLoader().getResource("config/config.sample.yml");
        String[] args = {"server","config.sample.yml"};
        brooklynServer.runAsync(args);
        applicationManager = brooklynServer.getApplicationManager();
    }

    @BeforeMethod
    public void setUpBeforeMethod() throws Exception {
        // Set i/o streams
        outBytes = new ByteArrayOutputStream();
        out = new PrintStream(outBytes);
        errBytes = new ByteArrayOutputStream();
        err = new PrintStream(errBytes);
        // Create a client instance
        brooklynClient = new Client(out,err);
    }

    @AfterClass
    public void tearDown() throws Exception {
        // Kill the REST server and client instance
        brooklynServer.stop();
    }

    @Test(enabled = false)
    public void testCatalogEntitiesCommand() throws Exception {
        try {
            // Run the catalog-entities commandb
            String[] args = {"catalog-entities"};
            brooklynClient.run(args);
            // Check that output matches what we expect
            assertThat(standardOut(), containsString("brooklyn.entity.basic.BasicEntity"));
        } catch (Exception e) {
            LOG.error("\nstdout="+standardOut()+"\nstderr="+standardErr()+"\n", e);
            throw e;
        }
    }

    @Test(enabled = true)
    public void testDeployCreatesApp() throws Exception {
        try {
            // Run the deploy command
            String[] args = {"deploy","--format","class", "brooklyn.cli.ExampleApp"};
            brooklynClient.run(args);
            // We should only have 1 app in the server's registry
            assertEquals(applicationManager.registry().size(), 1);
            // The name of that app should match what we have provided in the deploy command
            assertEquals(Iterables.getOnlyElement(applicationManager.registry().keySet()), ExampleApp.class.getName());
        } catch (Exception e) {
            LOG.error("stdout="+standardOut()+"; stderr="+standardErr(), e);
            throw e;
        }
    }
}

@@ -144,16 +144,92 @@
 rables;%0A
+import com.google.common.io.ByteStreams;%0Aimport com.google.common.io.Files;%0A
 import c
@@ -457,32 +457,53 @@
 ayOutputStream;%0A
+import java.io.File;%0A
 import java.io.P
@@ -530,17 +530,23 @@
 ava.
-net.URL;%0A
+io.InputStream;
 %0Aimp
@@ -1067,16 +1067,42 @@
 m err;%0A%0A
+    File tempConfigFile;%0A%0A
     prot
@@ -1282,25 +1282,32 @@
 public void 
-s
+oneTimeS
 etUp() throw
@@ -1335,202 +1335,144 @@
  // 
-Start the REST server%0A        brooklynServer = BrooklynService.newBrooklynService();%0A%0A        //TODO Create a temporary file for config.sample.yml, so can run in jenkins?%0A        //URL configUrl
+Create temporary config file%0A        tempConfigFile = File.createTempFile(%22server-config%22,%22.yml%22);%0A        InputStream configInputStream
  = g
@@ -1509,16 +1509,24 @@
 Resource
+AsStream
 (%22config
@@ -1559,53 +1559,331 @@
     
-String%5B%5D args = %7B%22server%22,%22config.sample.yml%22
+try %7B%0A            Files.write(ByteStreams.toByteArray(configInputStream), tempConfigFile);%0A        %7D finally %7B%0A            configInputStream.close();%0A        %7D%0A%0A        // Start the REST server%0A        brooklynServer = BrooklynService.newBrooklynService();%0A        String%5B%5D args = %7B%22server%22,tempConfigFile.getAbsolutePath()
 %7D;%0A 
@@ -2035,28 +2035,16 @@
 id setUp
-BeforeMethod
 () throw
@@ -2383,17 +2383,24 @@
 ic void 
-t
+oneTimeT
 earDown(
@@ -2499,24 +2499,85 @@
 ver.stop();%0A
+        // Delete temp file%0A        tempConfigFile.delete();%0A
     %7D%0A%0A    @
@@ -2595,12 +2595,11 @@
 d = 
-fals
+tru
 e)%0A 
@@ -2702,33 +2702,15 @@
 the 
-catalog-entities 
 command
-b
 %0A   
@@ -3213,31 +3213,24 @@
  // Run the 
-deploy 
 command%0A    

Make use of a temporary .yml server config file in tests