package jp.sourceforge.shovel.action.impl;

import static javax.servlet.http.HttpServletResponse.*;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;

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

import org.apache.commons.httpclient.util.DateUtil;

import jp.sourceforge.shovel.action.IDownloadFileAction;
import jp.sourceforge.shovel.annotation.Perform;
import jp.sourceforge.shovel.entity.IServerFile;
import jp.sourceforge.shovel.entity.IUser;
import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.form.IDownloadFileForm;
import jp.sourceforge.shovel.service.IDirectoryService;
import jp.sourceforge.shovel.service.IServerFileService;
import jp.sourceforge.shovel.service.IShovelService;

public class DownloadFileActionImpl implements IDownloadFileAction {
    IDownloadFileForm actionForm_;
    HttpServletRequest request_;
    HttpServletResponse response_;
    
    @Perform(CSRF=false, login=false)
    public String perform() throws Exception {
        IDirectoryService directoryService = getShovelService().getDirectoryService();
        String foreignKey = actionForm_.getForeignKey();
        long userId = actionForm_.getUserId();
        IUser user = null;
        if (foreignKey != null){
            user = directoryService.getUser(foreignKey);
        } else if (userId > 0) {
            //P3:PeraPeraPrv対応
            user = directoryService.getUser(userId);
        }
        if (user == null) {
            throw new ApplicationException("");
        }
        IServerFile serverFile = null;
        if (actionForm_.isBackground()) {
            serverFile = user.getBackgroundImage();
        } else {
            serverFile = user.getProfileImage();
        }
        if (serverFile == null) {
            throw new ApplicationException("");
        }
        if (!serverFile.isExists()) {
            return null;
        }
        
        //0.9.5以降はシステム側でサムネイルを作る
        IServerFileService serverFileService = getShovelService().getServerFileService();
        if (serverFileService.createThumbnail(serverFile, actionForm_.getSizeType())) {
            //コミットしたいので、同じURLにリダイレクト
            response_.setHeader("Location", (String)request_.getAttribute("request-url"));
            response_.setStatus(SC_MOVED_TEMPORARILY);
            return null;
        }
        
        String time = request_.getHeader("If-Modified-Since");
        if (time != null && time.length() > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(DateUtil.parseDate(time));
            if (calendar.getTimeInMillis() >= serverFile.getCreatedTime() / 1000 * 1000) {
                //変更ねーっす
                response_.setStatus(SC_NOT_MODIFIED);
                return null;
            }
        }
        
        OutputStream outputStream = null;
        ApplicationException e = null;
        try {
            outputStream = response_.getOutputStream();
            serverFile.download(outputStream, actionForm_.getSizeType());
        } catch (IOException cause) {
            //TODO
            e = new ApplicationException("");
            e.initCause(cause);
            throw e;
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException cause) {
                if (e == null) {
                    //TODO
                    e = new ApplicationException("");
                    e.initCause(cause);
                    throw e;
                }
            }
        }
        
        return null;
    }
    public void setRequest(HttpServletRequest request) {
        request_ = request;
    }
    public void setResponse(HttpServletResponse response) {
        response_ = response;
    }
    public void setDownloadFileForm(IDownloadFileForm actionForm) {
        actionForm_ = actionForm;
    }
    public IDirectoryService getDirectoryService() {
        return getShovelService().getDirectoryService();
    }
    public IShovelService getShovelService() {
        return (IShovelService)request_.getAttribute("shovelService");
    }
}
