/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as
 * published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * (L-GPL)
 * along with GECAMed. If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor
 * (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

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

import lu.tudor.santec.gecamed.core.utils.ServerConfig;

import org.apache.log4j.Logger;

/**
 * 
 * @author Jens Ferring jens.ferring@tudor.lu
 * 
 * @Version
 * <br>$Log: JNLPServlet.java,v $
 */
public class ClientServlet extends HttpServlet
{
	private static final long	serialVersionUID	= 1L;
	
	/** the logger Object for this class */
	private static Logger		logger				= Logger.getLogger(ClientServlet.class.getName());
	
	
	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public void doGet (HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		response.setContentType("application/zip");
		response.setDateHeader("Last-Modified", System.currentTimeMillis());
		
		// read jnlp-file from url
		File warFile = new File(ServerConfig.JBOSS_DIR + File.separator + "server" + File.separator
				+ "default" + File.separator + "deploy" + File.separator + "gecamed.war");
		FileInputStream fis = new FileInputStream(warFile);
		ZipInputStream zis = null;
		ZipOutputStream zos = null;
		
		try
		{
			zis = new ZipInputStream(new BufferedInputStream(fis));
			zos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
			zos.setLevel(0);
			
			// add the host
			String hostAddress = JNLPServlet.getHostIP(request, response);
			
			try
			{
				// now iterate through each item in the stream. The get next
				// entry call will return a ZipEntry for each file in the
				// stream
				String outpath;
				ZipEntry inEntry;
				ZipEntry outEntry;
				String entryName;
				while ((inEntry = zis.getNextEntry()) != null)
				{
					entryName = inEntry.getName();
					
					if (entryName.equals("native_libs.jar"))
					{
						extractDlls(zis, zos);
						continue;
					}
					else if (entryName.startsWith("lib/")
	            			|| entryName.startsWith("native_libs/")
							|| entryName.equals("GECAMedClient.jar")
							|| entryName.startsWith("startGECAMedClient")
							|| entryName.startsWith("icon."))
					{
						// Once we get the entry from the stream, the stream is
						// positioned read to read the raw data, and we keep
						// reading until read returns 0 or less.
						
						outpath = "GECAMedClient/" + entryName;
						outEntry = new ZipEntry(outpath);
						zos.putNextEntry(outEntry);
						try
						{
							int len = 0;
							byte[] buffer = new byte[2048];
							while ((len = zis.read(buffer)) > 0)
							{
								zos.write(buffer, 0, len);
							}
						}
						finally
						{
							zos.closeEntry();
						}
					}
				}
				
				try
				{
					outpath = "GECAMedClient/hostaddress.txt";
					outEntry = new ZipEntry(outpath);
					zos.putNextEntry(outEntry);
					zos.write(hostAddress.getBytes("UTF8"));
				}
				finally
				{
					zos.closeEntry();
				}
			}
			finally
			{
				// we must always close the zip file.
				zis.close();
				zos.close();
			}
			
			
//			byte[] buffer = new byte[2048];
//			int readTotal = 0;
//			int read;
//			while ((read = bis.read(buffer)) > 0)
//			{
//				readTotal += read;
//				bos.write(buffer);
//			}
//			bos.flush();
//			logger.info("GECAMedClient.zip Downloaded. " + readTotal + " bytes sent.");
		}
		catch (SocketException e)
		{
			logger.info("GECAMedClient.zip download canceled");
			zos = null;
		}
		catch (IOException e)
		{
			logger.error("Error during GECAMedClient.zip download.", e);
		}
		finally
		{
			if (zis != null)
			{
				try
				{
					zis.close();
				}
				catch (IOException e)
				{
					logger.error("Error closing the client download input stream.\n" + e.getMessage());
				}
			}
			
			if (zos != null)
			{
				try
				{
					zos.close();
				}
				catch (IOException e)
				{
					logger.error("Error closing the client download output stream.\n" + e.getMessage());
				}
			}
		}
	}
	
	
	private void extractDlls (ZipInputStream zis, ZipOutputStream zos)
	{
		String outpath;
		ZipEntry outEntry;
		ZipEntry inEntry;
		
		zis = new ZipInputStream(new BufferedInputStream(zis));
		
		try
		{
			while ((inEntry = zis.getNextEntry()) != null)
			{
				if (!inEntry.getName().endsWith(".dll"))
					continue;
				
				outpath = "GECAMedClient/native_libs/" + inEntry.getName();
				outEntry = new ZipEntry(outpath);
				zos.putNextEntry(outEntry);
				try
				{
					int len = 0;
					byte[] buffer = new byte[2048];
					while ((len = zis.read(buffer)) > 0)
					{
						zos.write(buffer, 0, len);
					}
				}
				finally
				{
					zos.closeEntry();
				}
			}
		}
		catch (IOException e)
		{
			logger.error("Error extracting the native dlls", e);
		}
	}
}
