package jp.hasc.hasctool.ui.commands;

import static jp.hasc.hasctool.ui.commands.ResourceStreamProvider.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import jp.hasc.hasctool.core.runtime.FileStreamProvider;
import jp.hasc.hasctool.core.runtime.RuntimeContext;
import jp.hasc.hasctool.core.util.CoreUtil;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.Path;

/**
 * ファイルシステムに直接入出力を行う {@link FileStreamProvider}です。
 * @author iwasaki
 */
public class RawFileStreamProvider implements FileStreamProvider {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(RawFileStreamProvider.class);

	private final IContainer baseContainer_;
	@SuppressWarnings("unused")
	private final RuntimeContext runtimeContext_;
	
	public RawFileStreamProvider(IContainer baseContainer,
			RuntimeContext runtimeContext) {
		baseContainer_ = baseContainer;
		runtimeContext_ = runtimeContext;
	}
	
	public static final String SCHEME="rawfile:";
	//private static Pattern PAT_PATH_PREFIX=Pattern.compile("^(//)?(/(?=[a-z]:))?",Pattern.CASE_INSENSITIVE);
	
	public static boolean isPathMatches(String path) {
		return path.startsWith(SCHEME);
	}
	
	protected File getFileFile(String path) {
		path = trimSchemePrefix(path);
		//
		if (path.startsWith(KEYWORD_PROJECT_ROOT)) {
			// プロジェクトパス
			IFile f = baseContainer_.getProject().getFile(path.substring(KEYWORD_PROJECT_ROOT.length()));
			return f.getRawLocation().toFile();
		}
		if (path.startsWith(KEYWORD_WORKSPACE_ROOT)) {
			// Workspaceパス
			IFile f = baseContainer_.getWorkspace().getRoot().getFile(new Path(path.substring(KEYWORD_WORKSPACE_ROOT.length())));
			return f.getRawLocation().toFile();
		}
		// 絶対パス
		return new File(path);
	}

	protected File getFolderFile(String path) {
		path = trimSchemePrefix(path);
		//
		if (path.startsWith(KEYWORD_PROJECT_ROOT)) {
			// プロジェクトパス
			IFolder f = baseContainer_.getProject().getFolder(path.substring(KEYWORD_PROJECT_ROOT.length()));
			return f.getRawLocation().toFile();
		}
		if (path.startsWith(KEYWORD_WORKSPACE_ROOT)) {
			// Workspaceパス
			IFolder f = baseContainer_.getWorkspace().getRoot().getFolder(new Path(path.substring(KEYWORD_WORKSPACE_ROOT.length())));
			return f.getRawLocation().toFile();
		}
		// 絶対パス
		return new File(path);
	}
	
	private static String trimSchemePrefix(String path) {
		if (path==null) throw new NullPointerException("path is null");
		// scheme文字列を除去
		if (isPathMatches(path)) {
			path=path.substring(SCHEME.length());
		}
		return path;
	}
	
	@Override
	public InputStream openInputStream(String path) {
		File f = getFileFile(path);
		try {
			return new FileInputStream(f);
		} catch (FileNotFoundException ex) {
			CoreUtil.throwAsRuntimeException(ex);
			return null;
		}
	}

	@Override
	public OutputStream openOutputStream(String path) {
		File f = getFileFile(path);
		mkdirs(f.getParentFile());
		try {
			return new FileOutputStream(f);
		} catch (FileNotFoundException ex) {
			CoreUtil.throwAsRuntimeException(ex);
			return null;
		}
	}
	
	private void mkdirs(File f) {
		if (f==null) return;
		try{
			f.mkdirs();
		}catch(Exception ex) {
			LOG.warn("Exception",ex);
		}
	}

	@Override
	public void listFileNames(String folderPath, List<String> out) {
		File dir = getFolderFile(folderPath);
		for(File f:dir.listFiles()) {
			if (!f.isFile()) continue;
			String cname = f.getName();
			if (ResourceStreamProvider.isFileNameToIgnore(cname)) continue;
			out.add(cname);
		}
	}

	@Override
	public void listSubFolderNames(String folderPath, List<String> out) {
		File dir = getFolderFile(folderPath);
		for(File f:dir.listFiles()) {
			if (!f.isDirectory()) continue;
			String cname = f.getName();
			if (ResourceStreamProvider.isFolderNameToIgnore(cname)) continue;
			out.add(cname);
		}
	}

}
