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 {

	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 sessionRedirected(final String redirection,
						final JingleSession jingleSession) {
					// TODO Auto-generated method stub
				}

				@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 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 sessionDeclined(final String reason,
						final JingleSession jingleSession) {
					System.out.println("Session "
							+ jingleSession.getResponder()
							+ "declined because " + reason);
				}

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

				}

				@Override
				public void sessionClosed(final String reason,
						final JingleSession jingleSession) {
					System.out.println("Session "
							+ jingleSession.getResponder() + "closed because "
							+ reason);
				}
			});
			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);

	}

	/**
	 * @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);
	}

}
