package org.sakaiproject.wontovlab.tool.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLConnection;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.wontovlab.logic.ExternalLogic;
import org.sakaiproject.wontovlab.logic.UtilLogic;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;


/**
 * The Image servlet for serving from absolute path.
 * @author BalusC
 * @link http://balusc.blogspot.com/2007/04/imageservlet.html
 */
public class LarUtilServlet extends HttpServlet 
{
	private static Log log = LogFactory.getLog(LarUtilServlet.class);
    

	protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException 
    {

		processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException 
    {
        processRequest(request, response);
    }
    
    /**
     * Process all requests to this Servlet. This method implements the
     * controller over the request. Based on the URL pattern an approprieted
     * method is called to process the request and prepare the response.
     * 
     * @param request
     *            attributes for Lar session management.
     * @param response
     *            attributes for Lar session management.
     * @throws IOException
     *             if some IO exception ocurrs.
     * @throws ServletException
     *             if some Servlet execution exception has occurred.
     */
    private void processRequest(HttpServletRequest request,
            HttpServletResponse response) throws IOException, ServletException 
    {
        log.debug(this.getClass().getName() + " is processing request");
        
        String jsp = null;

        if (request.getRequestURI().endsWith("/getImage")) 
        {
            // the photo of weblab was requested.
            jsp = getImage(request, response);
        }
        
        if (jsp == null) 
        {
            response.sendRedirect(request.getContextPath());
        } 
        else if (!"empty".equals(jsp)) 
        {
            request.getRequestDispatcher(jsp).forward(request, response);
        }
    }
	
	private String getImage(HttpServletRequest request, HttpServletResponse response) 
	{

        //Obtaining beans from Spring
		WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());  
        ExternalLogic externalLogic = (ExternalLogic)springContext.getBean("org_sakaiproject_wontovlab_logic_ExternalLogic");
		
        UtilLogic utilLogic = (UtilLogic)springContext.getBean("org_sakaiproject_wontovlab_logic_UtilLogic");
        
    	//Obtaining upload path from sakai properties
        String imageFilePath = externalLogic.getSakaiHomePath() + externalLogic.getSakaiPropertyValue("lv.experiment.image.path");
    	         
        // Get file name from request.
        String imageFileName = request.getParameter("file");

        // Check if file name is supplied to the request.
        if (imageFileName != null) 
        {
            // Strip "../" and "..\" (avoid directory sniffing by hackers!).
            imageFileName = imageFileName.replaceAll("\\.+(\\\\|/)", "");
        } 
        else 
        {
            // Do your thing if the file name is not supplied to the request.
            // Throw an exception, or show default/warning image, or just ignore it.
            return null;
        }

        // Prepare file object.
        File imageFile = new File(imageFilePath, imageFileName);

        // Check if file actually exists in filesystem.
        if (!imageFile.exists()) {
            // Do your thing if the file appears to be non-existing.
            // Throw an exception, or show default/warning image, or just ignore it.
            return null;
        }

        // Get content type by filename.
        String contentType = URLConnection.guessContentTypeFromName(imageFileName);

        // Check if file is actually an image (avoid download of other files by hackers!).
        // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
        if (contentType == null || !contentType.startsWith("image")) {
            // Do your thing if the file appears not being a real image.
            // Throw an exception, or show default/warning image, or just ignore it.
            return null;
        }

        // Prepare streams.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;

        try {
            // Open image file.
            input = new BufferedInputStream(new FileInputStream(imageFile));
            int contentLength = input.available();

            // Init servlet response.
            response.reset();
            response.setContentLength(contentLength);
            response.setContentType(contentType);
            response.setHeader(
                "Content-disposition", "inline; filename=\"" + imageFileName + "\"");
            output = new BufferedOutputStream(response.getOutputStream());

            // Write file contents to response.
            while (contentLength-- > 0) {
                output.write(input.read());
            }

            // Finalize task.
            output.flush();
        } catch (IOException e) {
            // Something went wrong?
            e.printStackTrace();
        } finally {
            // Gently close streams.
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    // Do your thing with the exception. Print it, log it or mail it.
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    // Do your thing with the exception. Print it, log it or mail it.
                    e.printStackTrace();
                }
            }
        }
        
        return "empty";
    }

}
