package org.eclipse.stem.ui.ge.servlet;
/*******************************************************************************
 * Copyright (c) 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/ 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;

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

import org.eclipse.stem.ui.Activator;


/**
 * SlideShowServlet sends back a valid KML file for a GET or POST
 * action
 * <pre>
 * The way that it works is this:
 *  
 *    A KML file is launched to GoogleEarth that 
 *    has a network link with the following URL
 *    http://localhost:8080/SlideShow/slideshow?id=<id>&amp;folder=<path>
 *    where <id> is a unique id
 *          <path> is the directory containing the 
 *            kml files generated by STEM.
 *    
 *     GoogleEarth will then issue http GET requests with 
 *     the specified URL which will cause this servlet's 
 *     doGet() method to be invoked.  
 *     
 *     It retrieves the correct file in one of 2 ways:
 *     
 *     The servlet keeps a map of info keyed by the <id> that
 *     has a list of files that was found in the folder 
 *     and a counter that is used to send back the N'th file.
 *     and increment N.
 *     
 *     If a filename was specified in the URL 
 *       http://localhost:8080/STEM/slideshow?...file=<filename>
 *     then that file will be read and returned to GE.
 *     This file will always be the most recently generated 
 *     KML file.  This will help ensure that GE does not fall
 *     behind the STEM simulation.  
 * </pre>      
 *             
 */
public class SlideShowServlet extends HttpServlet {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
   
	/**
	 * Used by this and other servlets to control debug output
	 */
    public static boolean DEBUG = false;
    
    //public static boolean DEBUG = true;
    /**
     * change to true to cause output to be sent to console instead 
     * of GE
     */
    private static final boolean TEST = false;
    
    private static final long start = new Date().getTime();
    /**
     * Servlet context.  
     * 
     */
    public static final String CONTEXT = "STEM";
    /**
     * default folder for KML files.
     */
    static final String STEM_FOLDER = "c:\\tmp\\ge";
    
    /**
     * collection of information about a session
     * Key = id passed to servlet 
     * 
     */       
    
    private static HashMap<String,SlideShowInfo> _infoMap = null;
    
    /**
     * set true when we get a request that only sets the BBox info
     */
    private boolean bboxSet = false;    
    /**
     *  Handle the initial setup 
     */
	public void init(ServletConfig config) throws ServletException {
		    super.init(config);
		    //debug("init: Default folder="+STEM_FOLDER);		 
		   
		    _infoMap = new HashMap<String,SlideShowInfo>();		    
		    
	 }
    
	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
		
		doPost(request, response);
}

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    protected void doPost(HttpServletRequest request,HttpServletResponse response) 
            throws ServletException, IOException {
    			
		int counter = 0;
			    
	    String fileName = null;
		SlideShowInfo info = null;
		
		File[] files = null;
		
		try {
			// get info from url
			info = getParameters(request);
			String key = info.getKey();
			if (bboxSet) {
				// This was a request to return BBOX only
				processNoOp(request,response);
			}
			// make sure there is some delay between requests
			info.delay();			
			fileName = info.getFileName();
			if (fileName != null) {	
				// get a specific file
				
				processFile(request,response,info,fileName); 
				return;
			} else {
			  // get saved list of files	
			  files = info.getFiles();
			  // if never filled in
			  if (files == null) {
				  // get updated list of files
				 files = getFiles(info);
			  }
			
			} 
			counter = getCounter(request,response,info);
			// getCounter will have updated info.getFiles
			files = info.getFiles(); // added files			
			if (files.length == 0) {
				// if no .kml files in folder
				if (info.isWaitForKML()) {
					sendScreenOverlay(request, response, "Waiting to Start");

				} else {
					response.sendError(HttpServletResponse.SC_BAD_REQUEST,
					"No KML files in specified folder.");
				}
				return;
			}	
			File kmlFile = files[counter];
//			String print = "key: "+key+" Counter: " + counter +
//			" addr: " + request.getServerName() + ":"+request.getServerPort()+
//			" #files: "+files.length +
//			" kmlFile: "+kmlFile.getAbsolutePath();
			//debug(print);
			debug("Send to GE: "+kmlFile);
			
			FileInputStream fis = new FileInputStream(kmlFile);
			// insert is additioal KML to be sent with output
			String[] insert = info.getInsert();
			
			sendOutput(request,response, fis,insert );
			info.setCounter(counter);
			_infoMap.put(key, info);
		} catch (Throwable e) {			
			e.printStackTrace();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
					e.getMessage());
		}
	}

	
    /**
     * Get the counter that keeps track of which file
     * is to be processed next.
     * 
     * It does more thatn just get the next value for the counter,
     * it will check if there are more files to process and if not
     * do the handling of this case.  
     * 
     * @param request  ServletRequest
     * @param response ServletResponse
     * @param info   instance of information saved from step to step
     * @return N where we want to display the Nth file
     *           from the specified folder.  
     *           0 if starting over 
     *           
     * @throws Exception
     */
    synchronized 
    private int getCounter(HttpServletRequest request,
    		               HttpServletResponse response,
    		               SlideShowInfo info) 
                               throws Exception{
		
		int counter = info.getCounter();
		counter++;
		
		// if done all of files currently in list
		int waits = 10; // wait for 10 seconds
		int max = info.getFiles().length;
		while (true) {
		  
		  if (counter >= max) {
 			 // reached end of filelist
			
			if (info.isWaitForKML()) {
				Thread.sleep(1*1000);
			    info.setFiles(null);
			    getFiles(info);
			    max = info.getFiles().length;
			    
			    waits--;
			    if (waits > 0) 
			    	continue;
			    // waited and still no more files
			    // indicate to user we are paused
			    counter = max-1;
			    if (! info.isPause()) {
					// if we have not yet claimed to be pausing
			        //debug("pause: ");									
                    info.setPause(true);	        
			        // send pause as icon to GE
                    String host = getHost(request);			
    		    	String url = "http://"+host+"/"+
    				    CONTEXT+"/image?text="+
    				    URLEncoder.encode("Paused","UTF-8");
    				String[] insert = buildScreenOverlay(url);
    				info.setInsert(insert);
			    }
			    break;
			} else {
				// pause before restarting
				// TODO remove debug
				debug("Pause 10 seconds before restarting");
				Thread.sleep(10*1000);
				counter = 0;
				break;
			}
		  } else {
			if (info.isPause()) {
				//debug("Change pause to active");
				// we were paused so change image to active
				info.setPause(false);
				Thread.sleep(2*1000);
				String host = getHost(request);			
		    	String url = "http://"+host+"/"+
				    CONTEXT+"/image?text="+
				    URLEncoder.encode("Active","UTF-8");
		    	
				String[] insert = buildScreenOverlay(url);
				info.setInsert(insert);
			    
			} 
			break;
		  } 
		} // while(true)
		
		return counter;	
		
    }
    /**
     * send back an empty response
     * 
     * @param request
     * @param response
     *
     * @throws ServletException
     * @throws IOException
     */
	
	private void processNoOp(HttpServletRequest request,
			HttpServletResponse response) 
	               throws ServletException, IOException{
		try {
			
			PrintWriter os = new PrintWriter(response.getOutputStream());
			//PrintStream os = System.out;
			response.setContentType("application/keyhole");

			os.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			os.println("<kml xmlns=\"http://earth.google.com/kml/2.0\">");
			os.println("<Document>");			
			os.println("</Document>");
			os.println("</kml>");

			os.flush(); 
		} catch (Throwable e) {			
			e.printStackTrace();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
		}
	}
    /**
     * Process a request to serve up a specific file
     * 
     * @param request
     * @param response
     * @param fileName
     * @throws ServletException
     * @throws IOException
     */
	
	private void processFile(HttpServletRequest request,
			HttpServletResponse response,
			SlideShowInfo info, String fileName) 
	               throws ServletException, IOException{
		try {
			
			File kmlFile = new File(fileName);	
			String oldFileName = fileName.replace("_Current","_Old");
			File oldFile = new File(oldFileName);
			String[] insert = info.getInsert();	
			FileInputStream fis  = null;
			int counter = 0;
            while (true) {            
			    try {
			    	if (! kmlFile.exists() ) {			    		
			    		Thread.sleep(2*1000);
			    		counter++;
			    		// after 20 seconds use old file
			    		if (counter > 10) {
			    			rename(oldFile,kmlFile);			    			
			    		} 
			    		continue;
			    	}
					fis = new FileInputStream(kmlFile);	
					//debug(" kmlFile: "+kmlFile.getAbsolutePath());
					break;
				} catch (Exception e) {					
					error("processFile failed",e);
					return;
				}				
            }
            debug("Send to GE: "+kmlFile);
            sendOutput(request,response, fis,insert );
           
            rename(kmlFile,oldFile);
            
		} catch (Throwable e) {			
			e.printStackTrace();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
		}
	}  
	
	
	/**
	 * switch files by renaming
	 */
	private boolean rename(File oldFile, File newFile) {
		try {
			if (newFile.exists()) 
				newFile.delete();
   
			oldFile.renameTo(newFile);
		} catch (RuntimeException e) {
			return false;
		}
		return true;
	}
	/**
	 * @param request
	 */
	private String getHost(HttpServletRequest request) {
		int port = request.getServerPort();		    	
		String host = request.getServerName()+":"+port;
		return host;
	}
	
    /**
     * Get the list of files in the folder
     *      
     *  
     * @param info  instance that holds misc info about session
     * @return array of Files in the specified folder
     */
    
    public File[] getFiles(SlideShowInfo info) {
		File[] files = null;
		File folder = null;
		try {
			files = info.getFiles();
			
			if (files == null || files.length == 0) {
				folder = new File(info.getFolderName());				
			    files = fileList(folder);
			    if (files == null)
					files = new File[0];
			    info.setFiles(files);
			}
		} catch (RuntimeException e) {
			
			error("getFiles() failed. ",e);
			files = new File[0];
		} 	
		
		return files;			
    }
    
/**
 * get the list of files in the specified folder.
 * The files will only be files with the ".kml" 
 * extension and will be sorted by filename.
 * Also netlink files will be filtered out
 * 
 * @param folder Directory that contains KML files to display
 * @return array of sorted filenames
 */
   
  private File[] fileList(File folder) {
    
    FileFilter ff = new FileFilter() {
		public boolean accept(File f){
			if (f.getName().toLowerCase().startsWith("net")) {
				return false;
			}
			if (f.getName().toLowerCase().endsWith(".kml")) {
				return true;
			}
			return false;
		}
	};	
	
	Comparator<? super File> compare = new Comparator<File>() {
		public int compare(File o1, File o2) {
			File f1 = (File)o1;
			File f2 = (File)o2;
			int answer = f1.getName().compareTo(f2.getName());
			return answer;
		}

	};
	
	try {						
		File[] files = folder.listFiles(ff);
		if (files == null) {
			return new File[0];
		}		
		Arrays.sort(files,0,files.length,compare);
		return files;
	} catch (Exception e) {		
		e.printStackTrace();
		return null;
	}
  }
  /**
	 * Obtain the following parameters from the URL.
	 * <pre>
	 *  id:  A key that makes this session unique
	 *    Because GoogleEarth sets up a new session for each 
     *   request, we cannot use the normal Servlet session 
     *   protocol.  
     *   We keep a hashmap of session info keyed by an ID that 
     *   is passed in the URL 
     *  
     *  folder:  Where to find the KML files
     *  
     *  delay:   Time to delay between returning data
     *  
     *  wait:    If "y" them if now new files send a "pause" icon
     *  
     *  file:    If spcified then return the specified file
     *   
	 *  BBOX:    If found then GE has return the current view coordinates
	 *  
	 *  BBoxSet: If found then GE has returned BBOX and no answer is 
	 *           required. 
	 *           
	 *  id is then used to access infoMap and
	 *  and return an instance of SlideShowInfo which contains current 
	 *  cycle counter, array of files and boolean wait indicator.
	 *  If there is no existing entry then it builds a new 
	 *  SlideShowInfo instance from the url parameters and stores 
	 *  it in the infoMap.
	 *  
	 * @param request  Servlet request instance.
	 * @return instance of SlideShowInfo 
	 */
	private SlideShowInfo getParameters(HttpServletRequest request) {
		// get the id from the URL parameters.
		// http://localhost:8080/slideshow?id=useridkey
		String mykey="DEFAULT";
	    String folderName = STEM_FOLDER;
	    boolean waitForKML = false;
	    String fileName = null;
	    String delay = "2";
	    String bbox = null;
	    bboxSet = false;
		Enumeration e = request.getParameterNames();
		StringBuffer sb = new StringBuffer();
		while (e.hasMoreElements()) {
			String name = (String)e.nextElement();
			String value = (String)request.getParameter(name);
			sb.append(name+": "+value+" ");
			if (name.equals("id")) {
				mykey = value;
			} else if (name.equals("folder")) {
				folderName = value;	
			} else if (name.equals("delay")) {
				delay = value;
				
			} else if (name.equals("wait")) {
				if (value.equals("y")) {
					waitForKML = true;
				}
			} else if (name.equals("file")) {
				fileName = value;
			} else if (name.equals("BBOX")) {
				bbox = value;
			} else if (name.equals("bboxSet")) {
				bboxSet = true;
			}
		}
		//debug("getParameters: "+sb.toString());
		SlideShowInfo info = _infoMap.get(mykey);
		if (info == null) {
			info = new SlideShowInfo(mykey,folderName,waitForKML,
					                 fileName,delay);			
		} 
		if (bbox != null)
			info.setBBOX(bbox);
		_infoMap.put(mykey,info);
		return info;
		
	}
	/**
	 * Send the KML file to the caller (GoogleEarth)
	 * 
	 * If TEST=true then it will be written to the browser 
	 * for testing.
	 * 	
     * @param request   
     * @param response
     * @param kml  InputStream holding file contents
     * @param insert  KML to be inserted in output
     * @throws IOException
     */
    synchronized 
    private void sendOutput(HttpServletRequest request,
			                HttpServletResponse response, 
			                InputStream  kml, String[] insert) 
	            throws IOException {
    	// set TEST=true to get readable output instead of 
    	// launching a KML file
    	      
		response.setContentType("application/keyhole");
    	
				
		try {
			OutputStream os = response.getOutputStream();			
			if (TEST) {
				os = System.out;
			}
			copy(kml,os,insert);
		} catch (Exception e) {
			String msg = "SlideShowServlet.sendOutput() failed while sending kmlFile";
			error(msg+"\n"+e.getMessage(),null);
			
		}
		
	}
    /**
     * build a segment of KML to be inserted into the 
     * output written to GoogleEarth.
     * 
     * @param url
     * @return KML to be inserted 
     */
    private String[] buildScreenOverlay( String url) {
		String[] insert = new String[] 
			{"<ScreenOverlay id=\"Status\">",
			 "   <description>STEM status</description>",
			 "   <name>Status</name>\n",
			 "<icon>",
			 "<href>",			
			 url,
			 "</href>",
			 "</icon>\n",
			 // following positions image to loop left
			 "<overlayXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>\n",
			 "<screenXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>\n",
			 // use actual size of image
			 "<size x=\"0\" y=\"0\" xunits=\"fraction\" yunits=\"fraction\"/>\n",
			 "</ScreenOverlay>\n"			
			 };
		
		return insert;
	}
	/**
	 * Send the KML file to the caller (GoogleEarth)
	 * 
	 * 
	 * @param response
	 * @param info
	 * @param msg A string that will be converted 
	 *      to an image and displayed by GoogleEarth
	 * @throws IOException
	 */
    
    private void sendScreenOverlay(HttpServletRequest request,
			                HttpServletResponse response, 
			                String msg) 
	            throws IOException {
    	    	      
		response.setContentType("application/keyhole");
    	
				
		try {
			String host = getHost(request);			
			String url = "http://"+host+"/"+
			     CONTEXT+"/image?text="+
			URLEncoder.encode(msg,"UTF-8");

			String[] insert = buildScreenOverlay(url);

			PrintWriter os = new PrintWriter(response.getOutputStream());
			//PrintStream os = System.out;
			response.setContentType("application/keyhole");

			os.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			os.println("<kml xmlns=\"http://earth.google.com/kml/2.0\">");
			os.println("<Document>");
			for (int i=0; i<insert.length; i++) {					
				os.println(insert[i]);
			}
			os.println("</Document>");
			os.println("</kml>");

			os.flush(); 
		} catch (Exception e) {
			String emsg = "SlideShowServlet.sendScreenOverlay() failed while writing kmlFile";
			error(emsg+"\n"+e.getMessage(),null);

		}
		
	}
  

	private static String getClock() {
		long now = new Date().getTime()-start;
		return Long.toString(now);
	}

	/**
	 * return the info instance associated with the specified key
	 * @param key 
	 * @return instance of SlideShowInfo
	 */
	public static SlideShowInfo getInfo(String key) {
		SlideShowInfo info = _infoMap.get(key);
		return info;
	}
	/**
	 * copy a KML file to the servlet response output stream
	 * and perhaps insert additional KML statements
	 * 
	 * @param is KML file input
	 * @param os Servlet response output stream
	 * @param insert optional statements to be inserted
	 *               after the <document> statement.
	 */
	private void copy(InputStream is, OutputStream os, String[] insert) 
	       throws IOException {
		
		InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr); 
		String line = null;
		
        
		try {
			
			while (true) {
				line = br.readLine();
				if (line == null)
					break;
				
				byte[] buffer = line.getBytes();
				os.write(buffer, 0, buffer.length);
				if (insert!=null && 
						line.toLowerCase().startsWith("<document>")) {
					for (int i=0; i<insert.length; i++) {						
						buffer = insert[i].getBytes();
						os.write(buffer, 0, buffer.length);
					}
				}
			}
			os.flush();
			os.close();
			is.close();
		} catch (Throwable e) {
			
			error("SlideShowServlet.copy(): Error while copying KML file. "
					+e.toString(),null);
			try {
				is.close();
				os.close();
			} catch (Exception e2) {
				// already reported it
			}
		}

    }
	
	  /**
     * print debug messages to the server log.
     * @param msg
     */
	public static void debug(String msg) {
		if (DEBUG) {		 
		  Activator.logInformation(getClock()+" GEServlet: "+msg);
		}
	}
	 
	/**
	 * debug output for exceptions
	 * @param msg
	 * @param e
	 */
	public static void error(String msg,Throwable e) {
		//log(msg,e);
		Activator.logInformation(msg);
		if (e != null)
			if (DEBUG)				
				e.printStackTrace();
			else 
				Activator.logInformation(e.toString());
		
	}
}  // class