package serverP2P;

import java.util.Scanner;
import serverP2P.ServerManagementUDP;
import serverP2P.ServerManagementTCP;
import tools.Directories;
import tools.Logger;
import tools.HostItem;
import tools.ServerPortRange;
import tools.TrackerPortRange;


/** Server only implementation
 * First argument of main method is port listened by the server, and is mandatory.
 * @author	Louis Royer
 * @author	Flavien Haas
 * @author	JS Auge
 * @version	1.0
 */
public class ServerP2P {
	private Directories directories;
	static private final String subdir = "seeded/";
	private Logger logger;
	private HostItem tracker;
	private HostItem server;

	/** Constructor with portServerstr containing a port number.
	 * @param hostnameServer	binded hostname
	 * @param portServer	binded port
	 * @param hostnameTracker	tracker hostname
	 * @param portTracker	tracker port
	 * @param isInteractive	true if application in interactive mode
	 */
	public ServerP2P(String hostnameServer, int portServer, String hostnameTracker, int portTracker, boolean isInteractive) {
		Scanner scanner = new Scanner(System.in);
		server = new HostItem(hostnameServer, portServer);
		tracker = new HostItem(hostnameTracker, portTracker);
		directories = new Directories("P2P_JAVA_PROJECT_SERVER_" + portServer);
		directories.createSubdir(subdir);
		logger = new Logger(directories.getDataHomeDirectory() + "server.log");
		System.out.println("Server will listen on port " + portServer + " and serve files from " + directories.getDataHomeDirectory() + subdir);
		if (isInteractive) {
			directories.askOpenDataHomeDirectory(subdir, scanner);
		}
		scanner.close();
	}

	/** Main program entry point
	 * first parameter is port number and is mandatory
	 * to test, run with: java serverP2P.ServerP2P
	 * @param args	parameters
	 */
		public static void main(String [] args) {
			final String defaultHostname = "localhost";
			final ServerPortRange serverPortRange = new ServerPortRange();
			final TrackerPortRange trackerPortRange = new TrackerPortRange();
			String hostnameServer = "";
			int portServer = 0;
			String hostnameTracker = "";
			int portTracker = 0;
			Scanner scanner = new Scanner(System.in);
			boolean isInteractive = false;

			if ((args.length != 5) && (args.length != 0)) {
				System.out.println("usage : java serveurP2P.ServeurP2P (interactive) or java serveurP2P.ServeurP2P -- <serveurHOSTNAME> <serveurPORT> <trackerHOSTNAME> <trackerPORT> (" + serverPortRange + " and " + trackerPortRange +")");
				System.exit(1);
			}
			else if (args.length == 5) {
				isInteractive = false;
				hostnameServer = args[1];
				portServer = Integer.valueOf(Integer.parseInt(args[2]));
				hostnameTracker = args[3];
				portTracker = Integer.valueOf(Integer.parseInt(args[4]));
			} else {
				isInteractive = true;
				// configure application
				System.out.println("Server, enter hostname to bind (default = localhost): ");
				hostnameServer = scanner.nextLine();
				if (hostnameServer.equals("")) {
					hostnameServer = defaultHostname;
					System.out.println("using default hostname : " + hostnameServer);
				}
				System.out.println("Enter port (default = " + serverPortRange.getDefaultPort() + "): ");
				String portServerStr = scanner.nextLine();
				if (portServerStr.equals("")) {
					portServer = serverPortRange.getDefaultPort();
					System.out.println("using default port : " + portServer);
				} else {
					portServer = Integer.valueOf(Integer.parseInt(portServerStr));
				}
				// configure tracker
				System.out.println("Enter hostname of tracker (default = localhost): ");
				hostnameTracker = scanner.nextLine();
				if (hostnameTracker.equals("")) {
					hostnameTracker = defaultHostname;
					System.out.println("tracker default hostname : " + hostnameTracker);
				}
				System.out.println("Enter tracker's port (default = " + trackerPortRange.getDefaultPort() + "): ");
				String portTrackerStr = scanner.nextLine();
				if (portTrackerStr.equals("")) {
					portTracker = trackerPortRange.getDefaultPort();
					System.out.println("using default port : " + portTracker);
				} else {
					portTracker = Integer.valueOf(Integer.parseInt(portTrackerStr));
				}
			}

			boolean serverInRange = serverPortRange.isPortInRange(portServer);
			boolean trackerInRange = trackerPortRange.isPortInRange(portTracker);
			if (serverInRange && trackerInRange) {
				System.out.println("using hostname : " + hostnameServer);
				System.out.println("using port : " + portServer);
				System.out.println("tracker hostname : " + hostnameTracker);
				System.out.println("tracker port : " + portTracker);
				ServerP2P s = new ServerP2P(hostnameServer, portServer, hostnameTracker, portTracker, isInteractive);
				ServerManagementUDP smudp = new ServerManagementUDP(s.directories.getDataHomeDirectory() + subdir, s.server, s.tracker, s.logger);
				ServerManagementTCP smtcp = new ServerManagementTCP(s.directories.getDataHomeDirectory() + subdir, s.server, s.tracker, s.logger);
				Thread tudp = new Thread(smudp);
				tudp.setName("server UDP P2P-JAVA-PROJECT");
				tudp.start();
				Thread ttcp = new Thread(smtcp);
				ttcp.setName("server TCP P2P-JAVA-PROJECT");
				ttcp.start();
			} else {
				if (!serverInRange) {
					System.err.println("SERVER: Port not in range. " + serverPortRange);
				}
				if (!trackerInRange) {
					System.err.println("TRACKER: Port not in range. " + trackerPortRange);
				}
				System.exit(2);
			}
		}
}
