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 < 4) {
	    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(args[3]);
	Thread.sleep(60000);
    }

}
