package io.subutai.core.security.broker;


import javax.naming.NamingException;

import org.bouncycastle.openpgp.PGPPublicKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.subutai.common.command.Request;
import io.subutai.common.command.RequestBuilder;
import io.subutai.common.settings.Common;
import io.subutai.common.util.JsonUtil;
import io.subutai.common.util.ServiceLocator;
import io.subutai.common.util.UUIDUtil;
import io.subutai.core.broker.api.TextMessagePostProcessor;
import io.subutai.core.registration.api.RegistrationManager;
import io.subutai.core.security.api.SecurityManager;
import io.subutai.core.security.api.crypto.EncryptionTool;


/**
 * This class encrypts outgoing messages
 */
public class MessageEncryptor implements TextMessagePostProcessor
{
    private static final Logger LOG = LoggerFactory.getLogger( MessageEncryptor.class.getName() );
    private static final String CLONE_CMD_REGEX = "\\s*subutai\\s*clone[\\s\\S]*?";

    private final boolean encryptionEnabled;


    public MessageEncryptor( final boolean encryptionEnabled )
    {
        this.encryptionEnabled = encryptionEnabled;
    }


    public static SecurityManager getSecurityManager() throws NamingException
    {
        return ServiceLocator.getServiceNoCache( SecurityManager.class );
    }


    public static RegistrationManager getRegistrationManager() throws NamingException
    {

        return ServiceLocator.getServiceNoCache( RegistrationManager.class );
    }


    @Override
    public String process( final String topic, final String message )
    {
        LOG.debug( String.format( "OUTGOING %s", message ) );

        //assume this is a host  topic
        if ( encryptionEnabled && UUIDUtil.isStringAUuid( topic ) )
        {
            try
            {
                EncryptionTool encryptionTool = getSecurityManager().getEncryptionTool();


                RequestWrapper requestWrapper = JsonUtil.fromJson( message, RequestWrapper.class );

                Request originalRequest = requestWrapper.getRequest();

                //obtain target host pub key for encrypting
                PGPPublicKey hostKeyForEncrypting = MessageEncryptor.getSecurityManager().getKeyManager()
                                                                    .getPublicKey( originalRequest.getId().toString() );

                if ( originalRequest.getCommand().toLowerCase().matches( CLONE_CMD_REGEX ) )
                {
                    //add token for container creation
                    originalRequest =
                            new RequestBuilder.RequestImpl( originalRequest.getType(), originalRequest.getId(),
                                    originalRequest.getCommandId(), originalRequest.getWorkingDirectory(),
                                    String.format( "%s -t %s", originalRequest.getCommand(), getRegistrationManager()
                                            .generateContainerTTLToken( ( originalRequest.getTimeout()
                                                    + Common.WAIT_CONTAINER_CONNECTION_SEC + 10 ) * 1000L )
                                            .getToken() ), originalRequest.getArgs(), originalRequest.getEnvironment(),
                                    originalRequest.getStdOut(), originalRequest.getStdErr(),
                                    originalRequest.getRunAs(), originalRequest.getTimeout(),
                                    originalRequest.isDaemon(), originalRequest.getConfigPoints(),
                                    originalRequest.getPid() );
                }

                String encryptedRequestString = new String( encryptionTool
                        .signAndEncrypt( JsonUtil.toJson( originalRequest ).getBytes(), hostKeyForEncrypting, true ) );

                EncryptedRequestWrapper encryptedRequestWrapper =
                        new EncryptedRequestWrapper( encryptedRequestString, originalRequest.getId() );

                return JsonUtil.toJson( encryptedRequestWrapper );
            }
            catch ( Exception e )
            {
                LOG.error( "Error in process", e );
            }
        }

        return message;
    }
}

@@ -36,16 +36,40 @@
 oker;%0A%0A%0A
+import java.util.List;%0A%0A
 import j
@@ -202,16 +202,57 @@
 ctory;%0A%0A
+import com.google.common.collect.Lists;%0A%0A
 import i
@@ -2589,32 +2589,72 @@
                 
+ List%3CString%3E args = Lists.newArrayList(
  originalRequest
@@ -2653,18 +2653,29 @@
 lRequest
- =
+.getArgs() );
 %0A       
@@ -2691,99 +2691,107 @@
     
-        new RequestBuilder.RequestImpl( originalRequest.getType(), originalRequest.getId(),
+args.add( %22-t%22 );%0A                    args.add( getRegistrationManager().generateContainerTTLToken(
 %0A   
@@ -2807,39 +2807,33 @@
                 
-       
+(
  originalRequest
@@ -2840,177 +2840,143 @@
 .get
-CommandId(), originalRequest.getWorkingDirectory(),%0A                                    String.format( %22%25s -t %25s%22, originalRequest.getCommand(), getRegistrationManager()
+Timeout() + Common.WAIT_CONTAINER_CONNECTION_SEC + 10 ) * 1000L )%0A                                                      .getToken() );%0A
 %0A   
@@ -2984,32 +2984,50 @@
                 
+originalRequest =%0A
                 
@@ -3038,66 +3038,95 @@
     
-.generateContainerTTLToken( ( originalRequest.getTimeout
+    new RequestBuilder.RequestImpl( originalRequest.getType(), originalRequest.getId
 ()
+,
 %0A   
@@ -3162,79 +3162,78 @@
     
-                + Common.WAIT_CONTAINER_CONNECTION_SEC + 10 ) * 1000L )
+originalRequest.getCommandId(), originalRequest.getWorkingDirectory(),
 %0A   
@@ -3268,31 +3268,8 @@
     
-         .getToken() ),
  ori
@@ -3284,22 +3284,31 @@
 uest.get
-A
+Command(), a
 rgs
-()
 , origin

fix container clone command SS-3083