package org.lantern.natty;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;

public class Natty {

    private final ConnectionConfiguration config;
    private final Connection gtalk;

    private ProcessBuilder builder;
    private Process process;
    private String offer;
    private String answer;
    private BufferedReader reader;
    private BufferedWriter writer;
    private boolean sendOffer;

    private SendFileServer fileServer;

    public Natty() {
      config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
      gtalk  = new XMPPConnection(config);
      offer  = null;
      fileServer = new SendFileServer(8585);
    }

    /**
     * @param args user name, password, and target
     * @throws XMPPException 
     * @throws InterruptedException 
     * @throws IOException 
     */
  
    public void connectGTalk(String user, String pass) throws XMPPException, 

        InterruptedException, IOException {

      gtalk.connect();
      gtalk.addPacketListener(new PacketListener() {

        @Override
        public void processPacket(final Packet pack) {
          System.out.println("PACKET FROM: "+pack.getFrom());
          final Message msg = (Message) pack;
          try { 
            if (msg.getBody().contains("offer")) {

              System.out.println("GOT OFFER " + msg.getBody());
              start("");
              sendAnswer();

              /* Reply with answer packet */
              msg.setTo(pack.getFrom());
              msg.setBody(answer);
              gtalk.sendPacket(msg);
            }
            else if (msg.getBody().contains("answer")) {
              System.out.println("GOT ANSWER " + msg.getBody());
              
            }
          }
          catch (IOException ioe) {
            ioe.printStackTrace();
            System.out.println("ERROR " + ioe);
          }
          catch (InterruptedException ie) {
            ie.printStackTrace();
            System.out.println("ERROR " + ie);
          }
        }
      }, new PacketFilter() {

        @Override
        public boolean accept(final Packet pack) {
          return pack instanceof Message;
        }
      });

      System.out.println("CONNNECTED?!?");

      gtalk.login(user, pass, "natty");

      final Roster roster = gtalk.getRoster();
      roster.addRosterListener(new RosterListener() {

        @Override
        public void presenceChanged(final Presence pres) {
          final String from = pres.getFrom();
          //System.out.println("GOT PRESENCE: "+from);
          if (from.contains("natty")) {
            final Message msg = new Message();
            msg.setTo(from);
            //System.out.println("Sending message: " + message);
            msg.setBody(offer);
            gtalk.sendPacket(msg);
          }
        }

      @Override
        public void entriesUpdated(Collection<String> arg0) {
        }

      @Override
        public void entriesDeleted(Collection<String> arg0) {
        }

      @Override
        public void entriesAdded(Collection<String> arg0) {
        }
      });

      final Collection<RosterEntry> entries = roster.getEntries();
      for (final RosterEntry re : entries) {
        System.out.println(re.getUser());
      }

    }

    private class Read extends Thread {

      private BufferedReader reader;

      public Read(BufferedReader reader) {
        this.reader = reader;
      }

      public void run() {
        try {
          String line;
          while ((line = this.reader.readLine()) != null) {
            if (line.contains("offer")) {
              offer = line;
            }
            else if (line.contains("answer")) {
              answer = line;
            }
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    private void sendAnswer() throws IOException, InterruptedException {
      System.out.println("Sending reply " + offer);
      writer.write(offer);
      writer.newLine();
      writer.flush();
      writer.close();
      Thread.sleep(4000);
    }

    private void start(final String target) throws IOException, InterruptedException, IOException {

        final List<String> command = new ArrayList<String>();
        command.add("./natty");
        command.add(target);
        builder = new ProcessBuilder(command);

        builder.redirectErrorStream(true);

        Map<String, String> environ = builder.environment();

        process = builder.start();

        /* initiate reader */
        final InputStream is = process.getInputStream();
        final InputStreamReader isr = new InputStreamReader(is);
        this.reader = new BufferedReader(isr);

        final OutputStream stdin = process.getOutputStream (); 
        this.writer = new BufferedWriter(new OutputStreamWriter(stdin));

        new Read(this.reader).start();
      }

    private void run() throws IOException, InterruptedException, IOException {
      start("-offer");
      Thread.sleep(30000);
    }

    public static void main(final String[] args) throws Exception {
      // Create a connection to the jabber.org server on a specific port.
      Natty natty = new Natty();
      final String user = args[0];
      final String pass = args[1];

      natty.connectGTalk(user, pass);
      natty.run();
    }

}

@@ -909,24 +909,195 @@
 ss Natty %7B%0A%0A
+    private static final int SENDFILESERVER_PORT = 8585; %0A    private static final int GTALK_PORT = 5222;%0A    private static final String GTALK_HOST = %22talk.google.com%22;%0A%0A
     private 
@@ -1396,22 +1396,21 @@
 ;%0A%0A    p
-rivate
+ublic
  SendFil
@@ -1498,31 +1498,30 @@
 ion(
-%22talk.google.com%22, 5222
+GTALK_HOST, GTALK_PORT
 , %22g
@@ -1634,20 +1634,35 @@
 eServer(
-8585
+SENDFILESERVER_PORT
 );%0A    %7D
@@ -2695,23 +2695,8 @@
 ));%0A
-              %0A
     
@@ -6235,16 +6235,47 @@
 gs%5B1%5D;%0A%0A
+      natty.fileServer.run();%0A%0A
       na

add some debugging info