/**
 * Copyright 2008-2009 DRIVER PROJECT (Bielefeld University)
 * Original author: Marek Imialek <marek.imialek at uni-bielefeld.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.dnetlib.data.utility.download.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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 org.semanticdesktop.aperture.mime.identifier.magic.MagicMimeTypeIdentifier;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import eu.dnetlib.common.utils.MimeType;

/**
 * The Class HttpProvideServlet.
 * 
 * @author <a href="mailto:marek.imialek at uni-bielefeld.de">Marek Imialek</a>
 */
public class HttpProvideServlet extends HttpServlet {
    
    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 123455787912873234L;

    /** The Constant log. */
	protected static final Logger log = Logger.getLogger(HttpProvideServlet.class);
    
    /** The mime type identifier. */
    private static MagicMimeTypeIdentifier mimeTypeIdentifier = new MagicMimeTypeIdentifier();
    
	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {
		
		try {
			String objectId = extractIdFromRequest(req);
			
			if (objectId == null || "".equals(objectId)) {
				String msg = "Object identifier not defined";
				log.error(msg);
				resp.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
    			return;
    		}
			
			HttpProvideServletProp servletProperties = 
				getBean("HttpServletProperties", HttpProvideServletProp.class);
    		
			String directory = servletProperties.getHttpServletSrcDirectory();
			
			if (directory == null || "".equals(directory)) {
				String msg = "Main directory not defined!";
				log.error(msg);
				resp.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
    			return;
    		}
			
			String objectPath = directory +"/"+ objectId;
			
			if (!(new File(objectPath)).exists()) {
				String msg = "Object " + objectId + " not found";
				log.error(msg);
    			resp.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
    			return;
    		}
			
    		InputStream is = new FileInputStream(objectPath);
    		OutputStream os = resp.getOutputStream();
    		
    		resp.setContentLength(is.available());
    		resp.setContentType(MimeType.identify(
					null, new FileInputStream(objectPath), 
					mimeTypeIdentifier));
   
    		try {    		
	    		byte[] buffer = new byte[is.available()];
	    		int size;
	    		while ((size = is.read(buffer)) >= 0) {
	    			os.write(buffer, 0, size);
	                os.flush();
	            }
			} finally {
			    os.close();
			}    						    		 
    
        } catch (Exception e) {
        	log.error(e.getMessage());
        	log(e.getMessage(), e);
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
        } 				
			
	}
	
	/**
	 * Extract id from request.
	 * 
	 * @param req the req
	 * 
	 * @return the string
	 */
	protected String extractIdFromRequest(HttpServletRequest req) {
		String id = req.getPathInfo();
		if (id != null) {
			if (id.startsWith("/")) id = id.substring(1);		
			return id;
		} else {
			return null;
		}
		
	}
	
	 /**
 	 * Gets the bean.
 	 * 
 	 * @param name the name
 	 * @param type the type
 	 * 
 	 * @return the bean
 	 */
 	protected <T> T getBean(String name, Class<T> type) {
	     WebApplicationContext ctx = 
             WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
	     @SuppressWarnings("unchecked")
	     T result = (T)ctx.getBean(name, type); 
	     return result;
	 }

}