package com.beem.project.beem.jingle;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.JingleSession;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
import org.jivesoftware.smackx.jingle.media.PayloadType;
import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;

/**
 * @author darisk
 */
public class Caller {

    /**
     * @param args
     *            Program args
     * @throws InterruptedException
     *             exception
     */
    public static void main(final String[] args) throws InterruptedException {
	if (args.length < 3) {
	    System.err.println("Not enough parameters");
	    System.err.println("Usage : Caller user password server jidtocall");
	}
	Caller test = new Caller(args[0], args[1], args[2]);
	test.call("test2@nikita-rack/TEST");
	Thread.sleep(60000);
    }

    private XMPPConnection           con;
    private String                   login;
    private String                   password;
    private JingleManager            jingleManager;
    private List<JingleMediaManager> mediaManagers;

    private JingleSession            out;

    public Caller(final String login, final String pass, String server) {
	if (server == null || server.equals(""))
	    server = "localhost";
	// XMPPConnection.DEBUG_ENABLED = true;
	this.login = login;
	this.password = pass;
	ConnectionConfiguration conf = new ConnectionConfiguration(server);
	conf.setRosterLoadedAtLogin(false);

	con = new XMPPConnection(conf);
	try {
	    con.connect();
	    con.login(this.login, this.password, "Caller");
	    initialize();
	} catch (XMPPException e) {
	    // TODO Auto-generated catch block
	    System.err.println("Echec de la connexion au serveru");
	    e.printStackTrace();
	}
    }

    public void call(final String destinataire) {
	try {
	    out = jingleManager.createOutgoingJingleSession(destinataire);
	    // TODO configure out avec addMediaSession et addNegociator
	    out.addListener(new JingleSessionListener() {

		@Override
		public void sessionClosed(final String reason, final JingleSession jingleSession) {
		    System.out.println("Session " + jingleSession.getResponder() + "closed because " + reason);
		}

		@Override
		public void sessionClosedOnError(final XMPPException e, final JingleSession jingleSession) {
		    System.out.println("Session " + jingleSession.getResponder() + " closed on error");

		}

		@Override
		public void sessionDeclined(final String reason, final JingleSession jingleSession) {
		    System.out.println("Session " + jingleSession.getResponder() + "declined because " + reason);
		}

		@Override
		public void sessionEstablished(final PayloadType pt, final TransportCandidate remoteCandidate,
		        final TransportCandidate localCandidate, final JingleSession jingleSession) {
		    System.out.println("Session established");
		    // String name = localCandidate.getName();
		    String ip = localCandidate.getIp();
		    int port = localCandidate.getPort();
		    System.out.println("Session established waiting connection on " + ip + ":" + port);
		    try {
			try {
			    FileSender fs = new FileSender(ip, port, "/tmp/img.jpeg");
			    fs.start();
			    fs.join();
			    System.out.println("End of transfer");
			} finally {
			    jingleSession.terminate();
			}
		    } catch (UnknownHostException e) {
			System.err.println("Can't create server");
		    } catch (InterruptedException e) {
		    } catch (XMPPException e) {
			System.err.println("Probably lost the connection");
			e.printStackTrace();
		    }
		}

		@Override
		public void sessionMediaReceived(final JingleSession jingleSession, final String participant) {
		    // TODO Auto-generated method stub
		    System.out.println("Session Media received from " + participant);
		}

		@Override
		public void sessionRedirected(final String redirection, final JingleSession jingleSession) {
		    // TODO Auto-generated method stub
		}
	    });
	    out.startOutgoing();

	} catch (XMPPException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

    }

    private void initialize() {
	mediaManagers = new ArrayList<JingleMediaManager>();
	mediaManagers.add(new SenderMediaManager(new BasicTransportManager()));
	JingleManager.setJingleServiceEnabled();
	jingleManager = new JingleManager(con, mediaManagers);

    }

}
