import java.io.*;
import java.net.*;

class MyThreadLecture extends Thread {
    private Socket s;
    public MyThreadLecture(Socket s) {
	this.s = s;
    }
    public void run() {
	try {
	    System.out.println("Reader thread");
	    // code bidon
	    byte []b = new byte[1];
	    s.getInputStream().read(b);
	    s.close();
	} catch(Exception ex) {
	    System.err.println("Error reading");
	}
    }
}
class MyThreadEcriture extends Thread {
    private Socket s;
    public MyThreadEcriture(Socket s) {
	this.s = s;
    }
    public void run() {
	try {
	    System.out.println("Writer thread");
	    // code bidon
	    byte []b = new byte[1];
	    s.getOutputStream().write(b);
	    s.close();
	} catch(Exception ex) {
	    System.err.println("Error writing");
	}
    }
}

public class ServeurTransfertFichier {
    public static void ecrit(Socket s) {
	System.out.println("ecrit");
	Thread t = new MyThreadEcriture(s);
	t.start();
    }
    public static void lit(ServerSocket s) {
	System.out.println("lit");
	try {
	    Thread t = new MyThreadLecture(s.accept());
	    t.start();
	} catch(Exception ex) {
	}
    }
    public static void envoyeur(Socket s) {
	System.out.println("Envoyeur");
	try {
	    OutputStream os = s.getOutputStream();
	    byte []out = new byte[1];
	    try {
		InputStream is = s.getInputStream();
		byte []in = new byte[4];
		is.read(in);
		InetAddress ia = InetAddress.getByAddress(in);
		System.out.println(ia);
		in = new byte[2];
		is.read(in);
		System.out.println("Read port : "+in[0]+" "+in[1]);
		int port = ((in[0]&0xff)<<8)+(in[1]&0xff);
		System.out.println("Port : "+port);
		Socket st = new Socket(ia,port);
		out[0] = (byte)'Y';
		os.write(out);
		os.flush();
		ecrit(st);
	    } catch(Exception ex) {
		out[0] = (byte)'N';
		os.write(out);
		os.flush();
	    }
	} catch(Exception ex) {
	}
    }
    public static void recepteur(Socket s) {
	System.out.println("Recepteur");
	try {
	    ServerSocket ss = null;
	    int port = 0;
	    for (port=49152; ss==null && port<65536; port++) {
		try {
		    ss = new ServerSocket(port);
		    break;
		} catch(Exception ex) {
		}
	    }
	    if (ss==null) port = 0;
	    System.out.println("Found port : "+port);
	    byte []out = new byte[2];
	    out[0] = (byte)(port>>>8);
	    out[1] = (byte)(port);
	    System.out.println("Found port : "+out[0]+" "+out[1]);
	    OutputStream os = s.getOutputStream();
	    os.write(out);
	    os.flush();
	    if (port!=0) lit(ss);
	} catch(Exception ex) {
	}
    }
    public static void main(String []args) {
	try {
	    ServerSocket ss = new ServerSocket(Transfert.PORT);
	    while (true) {
		System.out.println("Serveur is waiting for incoming packets");
		Socket s = ss.accept();
		byte []in = new byte[1];
		InputStream is = s.getInputStream();
		is.read(in);
		switch((char)in[0]) {
		case 'R' : recepteur(s); break;
		case 'E' : envoyeur(s); break;
		default: System.err.println("Something strange was read : "+in[0]);
		}
		System.out.println("Again...");
	    }
	} catch(Exception ex) {
	}
    }
}