/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2010, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * 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 org.jboss.as.server;

import org.jboss.as.model.Standalone;
import org.jboss.as.server.manager.ServerCommand;
import org.jboss.logging.Logger;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

/**
 * A MessageHandler.
 * 
 * @author Brian Stansberry
 * @author John E. Bailey
 */
class MessageHandler implements ServerCommunicationHandler.Handler {
    private static final Logger logger = Logger.getLogger("org.jboss.as.server");
    private final Server server;

    MessageHandler(Server server) {
        if (server == null) {
            throw new IllegalArgumentException("server is null");
        }
        this.server = server;
    }

    @Override
    public void handleMessage(byte[] message) {
        final ServerCommand serverCommand;
        try {
            serverCommand = readServerCommand(message);
        } catch (Exception e) {
            throw new RuntimeException("Failed to read server command", e);
        }

        if(serverCommand == null)
            throw new RuntimeException("Server command is null");

        switch(serverCommand.getCommand()) {
            case START:
                final Standalone standalone = (Standalone)serverCommand.getArgs()[0];
                try {
                    server.start(standalone);
                } catch (ServerStartException e) {
                    logger.error("Failed to start server", e);
                }
                break;
            case STOP:
                server.stop();
                break;
        }
    }

    private ServerCommand readServerCommand(byte[] message) throws IOException, ClassNotFoundException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(message);
        ObjectInputStream objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            final ServerCommand serverCommand = (ServerCommand)objectInputStream.readObject();
            return serverCommand;
        } finally {
            if(objectInputStream != null)
                objectInputStream.close();
        }
    }

    /* (non-Javadoc)
     * @see org.jboss.as.process.ProcessManagerSlave.Handler#handleMessage(java.lang.String, java.util.List)
     */
    @Override
    public void handleMessage(List<String> message) {
        logger.info("Message received: " + message);
    }

    @Override
    public void shutdown() {
        server.stop();        
    }

}

@@ -1055,24 +1055,50 @@
 as.server;%0A%0A
+import java.io.Closeable;%0A
 import org.j
@@ -1288,51 +1288,343 @@
 ava.
-io.ObjectInputStream;%0Aimport java.util.List
+util.List;%0Aimport org.jboss.marshalling.MarshallerFactory;%0Aimport org.jboss.marshalling.Marshalling;%0Aimport org.jboss.marshalling.MarshallingConfiguration;%0Aimport org.jboss.marshalling.ModularClassTable;%0Aimport org.jboss.marshalling.Unmarshaller;%0Aimport org.jboss.modules.ModuleClassLoader;%0Aimport org.jboss.modules.ModuleLoadException
 ;%0A%0A/
@@ -3150,119 +3150,161 @@
     
-ObjectInputStream objectInputStream = null;%0A        try %7B%0A            objectInputStream = new ObjectInputStream
+final Unmarshaller unmarshaller = MARSHALLER_FACTORY.createUnmarshaller(CONFIG);%0A        try %7B%0A            unmarshaller.start(Marshalling.createByteInput
 (byt
@@ -3321,16 +3321,17 @@
 tStream)
+)
 ;%0A      
@@ -3376,51 +3376,119 @@
 d = 
-(ServerCommand)objectInputStream.readObject
+unmarshaller.readObject(ServerCommand.class);%0A            unmarshaller.finish();%0A            unmarshaller.close
 ();%0A
@@ -3557,37 +3557,32 @@
     
-if(objectInputStream != null)
+safeClose(unmarshaller);
 %0A   
@@ -3590,42 +3590,213 @@
     
+%7D%0A
     
+%7D%0A%0A
     
-objectInputStream.close();
+private static void safeClose(final Closeable closeable) %7B%0A        if (closeable != null) try %7B%0A            closeable.close();%0A        %7D catch (Throwable ignored) %7B%0A            // todo: log me
 %0A   
@@ -4156,10 +4156,586 @@
 %0A    %7D%0A%0A
+    private static final MarshallerFactory MARSHALLER_FACTORY;%0A    private static final MarshallingConfiguration CONFIG;%0A%0A    static %7B%0A        try %7B%0A            MARSHALLER_FACTORY = Marshalling.getMarshallerFactory(%22river%22, ModuleClassLoader.forModuleName(%22org.jboss.marshalling:jboss-marshalling-river%22));%0A        %7D catch (ModuleLoadException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A        final MarshallingConfiguration config = new MarshallingConfiguration();%0A        config.setClassTable(ModularClassTable.getInstance());%0A        CONFIG = config;%0A    %7D%0A
 %7D%0A

Add dep on tools.jar.... for now