package org.yacos.web.system.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import org.yacos.core.article.Article;
import org.yacos.core.article.IArticleManager;

public class ArticleDownloadController implements Controller {
	private IArticleManager articleManager;
	private String downloadDirPath;
	
	public IArticleManager getArticleManager() {
		return articleManager;
	}
	
	public void setArticleManager(IArticleManager articleManager) {
		this.articleManager = articleManager;
	}
	
	public String getDownloadDirPath() {
		return downloadDirPath;
	}
	
	public void setDownloadDirPath(String downloadDirPath) {
		this.downloadDirPath = downloadDirPath;
	}

	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		try {
			Integer articleId = Integer.parseInt(request.getParameter("articleId"));
			Article article = articleManager.getArticle(articleId);
			
			File file = new File(downloadDirPath+article.getURL_article());
			
			long llength = file.length();
			
			if (llength > Integer.MAX_VALUE){
				throw new Exception("The file is too big");
			}
			int length = (int) llength;
			
			// We use a BufferedReader to avoid loading the whole file in memory at once
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			
			ServletContext servletContext = request.getSession().getServletContext();
			String mimetype = servletContext.getMimeType(file.getPath());
			
			// Sending file informations headers
			response.setBufferSize(length);
			response.setContentType(mimetype);
			response.setHeader("Content-Disposition", "attachment; filename=\""
					+ file.getName() + "\"");
			response.setContentLength(length);
			
			// Other headers that can prevent bugs with explorer
			response.setHeader("Cache-Control", "no-cache");
			response.setHeader("Pragma", "no-cache");
			response.setDateHeader("Expires", 0);
			
			// Copy the file to the output
			FileCopyUtils.copy(in, response.getOutputStream());
			in.close();
			
			response.getOutputStream().flush();
			response.getOutputStream().close();
			
		} catch(NumberFormatException e){
			// TODO : display something
			return null;
		}
		
		return null;
	}
	
	/**
	 * Simple utility method to load a file's content in a byte array
	 * @param file
	 * @return
	 * @throws Exception
	 */
	protected byte[] read(File file) throws Exception {
		InputStream in = new FileInputStream(file.getPath());
		long length = file.length();
		
		if (length > Integer.MAX_VALUE){
			throw new Exception("The file is too big");
		}
		
		byte[] data = new byte[(int) length];
		in.read(data);
		return data;
	}

}
