package yami;

import static com.google.common.collect.Lists.*;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import yami.configuration.Peer;
import yami.model.Constants;
import yami.model.DataStoreRetriever;
import yami.model.Result;
import yami.utils.ProcessExecuter;

public class AllPeersRestartServlet extends HttpServlet
{
	private static class PeerRestartThread implements Runnable
	{
		private final List<String> m_command;
		private Result result;
		
		private PeerRestartThread(List<String> command)
		{
			m_command = command;
		}
		
		@Override
		public void run()
		{
			try
			{
				log.info("running worker " + m_command);
				result = ProcessExecuter.execute(m_command);
			}
			catch (Exception ex)
			{
				log.warn("error in restart" , ex);
			}
		}

		public Result result()
		{
			return result;
		}
	}

	private static final Logger log = Logger.getLogger(AllPeersRestartServlet.class);
	private static final long serialVersionUID = 1L;
	private static final long SILENT_PERIOD = TimeUnit.MINUTES.toMillis(5);
	private PrintWriter writer;
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
	{
		log.info("ClientRestartServlet started");
		writer = res.getWriter();
		writeLine("Recived restart all peers request");
		ExecutorService executor = Executors.newFixedThreadPool(10);
		for (Peer peer : DataStoreRetriever.getD().peers())
		{
			restartPeer(peer, executor);
		}
		writeLine("waiting for threads");
		executor.shutdown();
		while (!executor.isTerminated()) {
			try
			{
				Thread.sleep(1000);
			}
			catch (InterruptedException ex)
			{
				ex.printStackTrace();
			}
		}
		writer.println("finished!");
		log.info("doGet() - restarting finished");
	}

	private void restartPeer(Peer peer, ExecutorService executor)
	{
		log.info("doGet() - restarting " + peer);
		DataStoreRetriever.getD().addSilentPeriod(peer, System.currentTimeMillis() + SILENT_PERIOD);
		final List<String> command = newArrayList(Constants.getInstallDir() + "/bin/restartAllPeers");
		command.add(peer.name);
		PeerRestartThread worker = new PeerRestartThread(command);
		executor.execute(worker);
		writeResult(peer, command, worker.result());
	}

	private void writeResult(Peer peer, List<String> command, Result r)
	{
		writeLine(">>> peer " + peer.name + " ; executing " + command);
		writeLine(r.output);
		writeLine("finished with status " + r.exit());
	}

	private synchronized void writeLine(String x)
	{
		writer.println(x);
		writer.flush();
	}
	
}

@@ -693,23 +693,16 @@
 private 
-static 
 class Pe
@@ -790,29 +790,33 @@
 private 
-Result result
+final Peer m_peer
 ;%0A%09%09%0A%09%09p
@@ -840,16 +840,27 @@
 tThread(
+Peer peer, 
 List%3CStr
@@ -877,16 +877,34 @@
 nd)%0A%09%09%7B%0A
+%09%09%09m_peer = peer;%0A
 %09%09%09m_com
@@ -1023,16 +1023,23 @@
 d);%0A%09%09%09%09
+Result 
 result =
@@ -1075,16 +1075,151 @@
 mmand);%0A
+%09%09%09%09if (null != result)%0A%09%09%09%09%7B%0A%09%09%09%09%09writeResult(m_peer, m_command, result);%0A%09%09%09%09%7D%0A%09%09%09%09else%0A%09%09%09%09%7B%0A%09%09%09%09%09log.warn(%22result is null%22);%0A%09%09%09%09%7D%0A
 %09%09%09%7D%0A%09%09%09
@@ -1295,60 +1295,8 @@
 %0A%09%09%7D
-%0A%0A%09%09public Result result()%0A%09%09%7B%0A%09%09%09return result;%0A%09%09%7D
 %0A%09%7D%0A
@@ -1648,24 +1648,190 @@
 xception%0A%09%7B%0A
+%09%09try%0A%09%09%7B%0A%09%09%09doRestart(res);%0A%09%09%7D%0A%09%09catch (Exception ex)%0A%09%09%7B%0A%09%09%09log.warn(%22error %22 ,ex);%0A%09%09%7D%0A%09%7D%0A%0A%09private void doRestart(HttpServletResponse res) throws IOException%0A%09%7B%0A
 %09%09log.info(%22
@@ -2768,16 +2768,22 @@
 tThread(
+peer, 
 command)
@@ -2816,55 +2816,8 @@
 r);%0A
-%09%09writeResult(peer, command, worker.result());%0A
 %09%7D%0A%0A

improve restart logs