package jp.sf.amateras.rdiffbackup.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import jp.sf.amateras.rdiffbackup.dto.FileDto;
import jp.sf.amateras.rdiffbackup.form.BrowseForm;
import jp.sf.amateras.rdiffbackup.util.FileDtoComparator;
import jp.sf.amateras.rdiffbackup.util.IconManager;
import jp.sf.amateras.rdiffbackup.util.PathUtil;

import org.apache.commons.io.IOUtils;
import org.seasar.framework.util.StringUtil;
import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.taglib.S2Functions;
import org.seasar.struts.util.ResponseUtil;

/**
 * 指定されたディレクトリのファイルを一覧表示するアクションです。
 *
 * @author Naoki Takezoe
 */
public class BrowseAction {

	///////////////////////////////////////////////////////////////
	// 表示用プロパティ
	///////////////////////////////////////////////////////////////

	/**
	 * バックアップディレクトリのルートディレクトリ
	 */
	public String root;

	/**
	 * 表示対象のディレクトリのパス
	 */
	public String path;

	/**
	 * 親ディレクトリのパス
	 */
	public String parentPath;

	/**
	 * ファイルの一覧
	 */
	public List<FileDto> files;

	///////////////////////////////////////////////////////////////
	// DI用プロパティ
	///////////////////////////////////////////////////////////////

	/**
	 * アクションフォーム
	 */
	@Resource
	@ActionForm
	protected BrowseForm browseForm;

	///////////////////////////////////////////////////////////////
	// 実行メソッド
	///////////////////////////////////////////////////////////////

	/**
	 * 指定されたディレクトリのファイルおよびディレクトリを一覧表示します。
	 *
	 * @return "index.jsp"
	 */
	@Execute(validator=true, input="/error.jsp")
	public String index(){
		// セキュリティチェック
		PathUtil.checkRoot(browseForm.root);
		PathUtil.checkPath(browseForm.path);

		// 処理対象のパスを作成
		String path = PathUtil.buildPath(browseForm.root, browseForm.path);

		this.root = browseForm.root;
		this.path = browseForm.path;

		if(StringUtil.isEmpty(this.path)){
			this.parentPath = "";
		} else {
			this.parentPath = String.format(
					"browse/?root=%s&path=%s",
					S2Functions.u(this.root),
					S2Functions.u(PathUtil.getParentPath(this.path)));
		}

		// ファイルの一覧を取得
		files = new ArrayList<FileDto>();

		File dir = new File(path);
		for(File file: dir.listFiles()){
			// rdiff-backupのメタファイルは除く
			if(file.isDirectory() && file.getName().equals("rdiff-backup-data")){
				continue;
			}

			FileDto fileDto = new FileDto();
			fileDto.name = file.getName();
			fileDto.isFile = file.isFile();
			fileDto.path = PathUtil.buildPath(browseForm.path, file.getName());
			fileDto.date = new Date(file.lastModified());
			fileDto.icon = IconManager.getIcon(file);

			if(!fileDto.isFile){
				fileDto.name = fileDto.name + "/";
				fileDto.path = fileDto.path + "/";
			}

			files.add(fileDto);
		}

		// ソートする
		Collections.sort(files, new FileDtoComparator());

		return "index.jsp";
	}

	/**
	 * 指定されたファイルの最新のバックアップをダウンロードします。
	 *
	 * @return null
	 */
	@Execute(validator=true, input="/error.jsp")
	public String download(){
		// セキュリティチェック
		PathUtil.checkRoot(browseForm.root);
		PathUtil.checkPath(browseForm.path);

		// 処理対象のパスを作成
		String path = PathUtil.buildPath(browseForm.root, browseForm.path);

		InputStream in = null;

		try {
			File file = new File(path);
			in = new FileInputStream(file);

			ResponseUtil.download(PathUtil.getDownloadFileName(file.getName()), in);

		} catch(IOException ex){
			throw new RuntimeException(ex);

		} finally {
			IOUtils.closeQuietly(in);
		}

		return null;
	}

}
