package me.normanmaurer.niosmtp.impl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import me.normanmaurer.niosmtp.DeliveryRecipientStatus;
import me.normanmaurer.niosmtp.SMTPClient;
import me.normanmaurer.niosmtp.SMTPClientConfig;
import me.normanmaurer.niosmtp.SMTPClientFuture;
import me.normanmaurer.niosmtp.SMTPCommand;
import me.normanmaurer.niosmtp.impl.internal.ChannelLocalSupport;
import me.normanmaurer.niosmtp.impl.internal.SMTPClientConfigImpl;
import me.normanmaurer.niosmtp.impl.internal.SMTPClientFutureImpl;
import me.normanmaurer.niosmtp.impl.internal.SMTPClientPipelineFactory;

/**
 * {@link SMTPClient} implementation which will create a new Connection for
 * every
 * {@link #deliver(InetSocketAddress, String, List, InputStream, SMTPClientConfig)}
 * call.
 * 
 * So no pooling is active
 * 
 * @author Norman Maurer
 * 
 */
public class UnpooledSMTPClient implements SMTPClient, ChannelLocalSupport {

    protected final NioClientSocketChannelFactory socketFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());


    protected ChannelPipelineFactory createChannelPipelineFactory() {
        return new SMTPClientPipelineFactory();
    }
    
    /*
     * (non-Javadoc)
     * @see me.normanmaurer.niosmtp.SMTPClient#deliver(java.net.InetSocketAddress, java.lang.String, java.util.List, java.io.InputStream, me.normanmaurer.niosmtp.SMTPClientConfig)
     */
    public SMTPClientFuture deliver(InetSocketAddress host, final String mailFrom, final List<String> recipients, final InputStream msg, final SMTPClientConfig config) {
        final SMTPClientFutureImpl future = new SMTPClientFutureImpl();
        ClientBootstrap bootstrap = new ClientBootstrap(socketFactory);
        bootstrap.setPipelineFactory(createChannelPipelineFactory());
        InetSocketAddress local = config.getLocalAddress();
        bootstrap.connect(host, local).addListener(new ChannelFutureListener() {
            
            @Override
            public void operationComplete(ChannelFuture cf) throws Exception {
                Map<String, Object> attrs = new HashMap<String, Object>();
                attrs.put(FUTURE_KEY, future);
                attrs.put(NEXT_COMMAND_KEY, SMTPCommand.HELO);
                attrs.put(MAIL_FROM_KEY, mailFrom);
                attrs.put(RECIPIENTS_KEY, new LinkedList<String>(recipients));
                attrs.put(MSG_KEY, msg);
                attrs.put(SMTP_CONFIG_KEY, config);
                ATTRIBUTES.set(cf.getChannel(), attrs);
                
                // Set the channel so we can close it for cancel later
                future.setChannel(cf.getChannel());
            }
        });
        return future;
    }

    /**
     * Call this method to destroy the {@link SMTPClient} and release all resources
     */
    public void destroy() {
        socketFactory.releaseExternalResources();
    }

    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        UnpooledSMTPClient client = new UnpooledSMTPClient();
        SMTPClientFuture future = client.deliver(new InetSocketAddress("192.168.0.254", 25), "test@test.de", Arrays.asList("nm@normanmaurer.me", "nm2@normanmaurer.me"), new ByteArrayInputStream("Subject: test\r\n\r\ntest".getBytes()), new SMTPClientConfigImpl());
        Iterator<DeliveryRecipientStatus> statusIt = future.get();
        while(statusIt.hasNext()) {
            DeliveryRecipientStatus rs = statusIt.next();
            System.out.println(rs.getAddress() + "=> " + rs.getResponse().getCode() + " " + rs.getResponse().getLines().toString());
        }
    }
}

@@ -2638,32 +2638,74 @@
 ows Exception %7B%0A
+                if (cf.isSuccess()) %7B%0A    
                 
@@ -2771,32 +2771,36 @@
                 
+    
 attrs.put(FUTURE
@@ -2822,32 +2822,36 @@
                 
+  
+  
 attrs.put(NEXT_C
@@ -2889,32 +2889,36 @@
                 
+    
 attrs.put(MAIL_F
@@ -2945,32 +2945,36 @@
                 
+   
+ 
 attrs.put(RECIPI
@@ -3016,24 +3016,28 @@
 cipients));%0A
+    
             
@@ -3073,32 +3073,36 @@
                 
+    
 attrs.put(SMTP_C
@@ -3137,16 +3137,20 @@
         
+ 
+   
 ATTRIBUT
@@ -3189,32 +3189,114 @@
                 
+%7D else %7B%0A                    // TODO: Handle connection problems%0A                %7D
 %0A               

Add a todo