package com.beem.project.beem.jingle;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.JingleSession;
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
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;
import org.jivesoftware.smackx.packet.DiscoverInfo;


public class Receiver {

    private XMPPConnection con;
    private JingleManager jingleManager;
    private List<JingleMediaManager> mediaManagers;
    private JingleSession in;

    public Receiver(String username, String pass) {
	//		XMPPConnection.DEBUG_ENABLED = true;
	ConnectionConfiguration conf = new ConnectionConfiguration("nikita-rack");
	conf.setRosterLoadedAtLogin(false);
	con = new XMPPConnection(conf);
	
	try {
		
	    con.connect();
	    JingleManager.setJingleServiceEnabled();
		ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(con);
	    //NOTE  Classe gerant le service discovery (ce qui permet aux autres de savoir ce qu'on sait faire)
	    
	    
	    //Pour rajouter une liste de feature supporter (de format : "http://jabber.org/protocol/disco#info")
	    sdm.addFeature("http://jabber.org/protocol/disco#info");
	    sdm.addFeature("TOTO");
	    
	    con.login(username, pass, "TEST-JAVA");
	    initialize();
	    // Le client demande les services dispo en face a son roster
	    // il doit en suite fournir lui meme une liste de feature
	    
	    DiscoverInfo di = sdm.discoverInfo("test@nikita-rack/pidgin");
	    DiscoverInfo di2 = sdm.discoverInfo("nikita@nikita-rack/Telepathy");

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

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

	    @Override
	    public void sessionRequested(JingleSessionRequest request) {
		System.out.println("Jingle Session request from "+request.getFrom());
		try {
		    in = request.accept();
		    // TODO configure in
		    in.addListener(new JingleSessionListener() {

			@Override
			public void sessionRedirected(String redirection,
			    JingleSession jingleSession) {
			    // TODO Auto-generated method stub

			}

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

			@Override
			public void sessionEstablished(PayloadType pt,
			    TransportCandidate remoteCandidate,
			    TransportCandidate localCandidate, JingleSession jingleSession) {
			    // TODO Auto-generated method stub
			    System.out.println("Session established");
			    try{
				System.out.println("Je recois sur " + remoteCandidate.getIp() + ":" + remoteCandidate.getPort() );
				receiveData(remoteCandidate.getIp(), remoteCandidate.getPort());
			    } catch (IOException e){
				e.printStackTrace();
			    }
			}

			@Override
			public void sessionDeclined(String reason, JingleSession jingleSession) {
			    // TODO Auto-generated method stub
			    System.out.println("Session "+ jingleSession.getResponder() +"declined because "+ reason);
			}

			@Override
			public void sessionClosedOnError(XMPPException e,
				JingleSession jingleSession) {
			    // TODO Auto-generated method stub
			    System.out.println("Session "+ jingleSession.getResponder() + " closed"); 

			}

			@Override
			public void sessionClosed(String reason, JingleSession jingleSession) {
			    // TODO Auto-generated method stub
			    System.out.println("Session "+ jingleSession.getResponder() +"closedd because "+ reason);
			}
		    });
		    in.startIncoming();
		} catch (XMPPException e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	    }
	});

    }


    private void receiveData(String ip, int port) throws IOException {
	Socket s = null;
	try {
	    s = new Socket(ip, port); 
	    System.out.println("Waiting data");
	    InputStream in = s.getInputStream();
	    int a;
	    while ( (a = in.read()) != -1) {
		System.out.println("Received " + a);
	    }
	    System.out.println("End receiving data");
	} finally {
	    if (s != null)
		s.close();
	}
    }

    /**
     * @param args
     * @throws InterruptedException 
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
	// TODO Auto-generated method stub
	Receiver rec = new Receiver("test2", "test2");
	System.out.println("Receiver initialized");

	Thread.sleep(60000);

    }

}
