package com.interpress_project.modernshare.client.controller.actions;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;

import com.interpress_project.modernshare.client.controller.command.SVNCommandFactory;
import com.interpress_project.modernshare.client.controller.command.SVNCommandManager;
import com.interpress_project.modernshare.client.controller.command.TaskManager;
import com.interpress_project.modernshare.client.controller.delegate.LocalSVNManager;
import com.interpress_project.modernshare.client.controller.delegate.SVNFolderUtil;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.AccountNotFoundException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.ConnectionFailException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.DeleteFailException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.TagExistException;
import com.interpress_project.modernshare.client.controller.model.LocalModelManager;
import com.interpress_project.modernshare.client.events.GUIEvent;
import com.interpress_project.modernshare.client.events.GUIEventType;
import com.interpress_project.modernshare.client.events.LogEvent;
import com.interpress_project.modernshare.client.events.LogEventType;
import com.interpress_project.modernshare.client.view.ViewManager;

/**
 *@stereotype action
 */
public final class UnRegisterTargetAction extends ActionAdaptor {
	private final ViewManager vmgr;
	private final SVNCommandManager cmdmgr = SVNCommandManager.getInstance();
	private final SVNCommandFactory factory = SVNCommandFactory.getInstance();
	private String path, tagName;

	/**
	 * UnRegisterTargetAction
	 * @param vmgr
	 * @param path
	 * @param tagName
	 */
	public UnRegisterTargetAction(ViewManager vmgr, String path, String tagName) {
		setText("ホットショットフォルダの登録解除とリポジトリデータの削除(&X)");
		setToolTipText("ローカルフォルダの監視を解除します。");
		try {
			setImageDescriptor(ImageFactory.getInstance().getImageDescriptor("delete"));
		}
		catch (Exception ex) {
			sb.getLogger().fatal("リソース設定のエラーが発生しました。", ex);
			System.exit(-1);
		}
		this.vmgr = vmgr;
		this.path = path;
		this.tagName = tagName;
	}

	/**
	 * run
	 */
	public void run() {
		TaskManager taskmgr = TaskManager.getInstance();
		try {
			taskmgr.stop();

			logEventSource.fireEvent(new LogEvent(this, LogEventType.CLEAR));

			boolean bRes = vmgr.getDialogManager().createYesNoMessageDialog(path + "の登録解除",
			  "ローカルフォルダ" + path + "の監視登録を解除します。(ローカルフォルダは削除されません。)");
			if (bRes == false) {
				return;
			}
			ProgressMonitorDialog dlg = new ProgressMonitorDialog(vmgr.getShell());

			IRunnableWithProgress op = new UnRegisterCommand();
			dlg.run(true, false, op);
		}
		catch (Exception ex) {
			sb.getLogger().error(ex.getMessage(), ex);
			vmgr.getDialogManager().createErrorMessageDialog(ex.getMessage());
		}
		finally {
			taskmgr.start();
		}
		guiEventSource.fireEvent(new GUIEvent(this, "ローカルフォルダ" + path + "の監視登録を解除しました。", GUIEventType.FINISH));
	}

	/**
	 * UnRegisterCommand class
	 * @author ys
	 */
	private class UnRegisterCommand implements IRunnableWithProgress {
		/**
		 * run
		 */
		public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
			final LocalSVNManager svnmgr = LocalSVNManager.getInstance();
			String msg = null;
			boolean bRemote = false;

			monitor.beginTask("ローカルフォルダの監視登録の解除", 8);

			// Step.1 check file
			File file = new File(path);
			if (!file.exists()) {
				monitor.subTask("ローカルフォルダ" + path + "は存在しません。");
			}
			monitor.worked(1);

			// Step.2 
			msg = "データセンタに接続をしています...";
			monitor.subTask(msg);
			logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
			try {
				svnmgr.connect();
			}
			catch (ConnectionFailException ex) {
				throw new InvocationTargetException(ex, ex.getCause().getMessage());
			}
			monitor.worked(1);

			// Step.3
			msg = "アカウントを確認しています...";
			monitor.subTask(msg);
			try {
				svnmgr.existAccount();
			}
			catch (AccountNotFoundException ex) {
				throw new InvocationTargetException(ex, ex.getCause().getMessage());
			}
			monitor.worked(1);

			try {
				// Step.4 
				msg = "タグ名を確認しています...";
				monitor.subTask(msg);
				logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
				svnmgr.existTagName(tagName);
				monitor.worked(1);
			}
			catch (TagExistException ex) {
				bRemote = true;
			}
			catch (Exception ex) {
				throw new InvocationTargetException(ex, ex.getMessage());
			}

			if (bRemote) {
				try {
					// Step.5
					msg = "リモートフォルダを削除しています...";
					monitor.subTask(msg);
					logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
					svnmgr.deleteRemoteFolder(tagName);
				}
				catch (Exception ex) {
					throw new InvocationTargetException(ex, ex.getMessage());
				}
			}
			monitor.worked(1);

			// Step.6
			msg = "ローカルフォルダから管理フォルダを削除しています...";
			monitor.subTask(msg);
			logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
			SVNFolderUtil futil = SVNFolderUtil.getInstance();
			ArrayList<File> list = futil.getSVNDirListInTarget(new File(path));
			try {
				futil.deleteFiles(list);
			}
			catch (DeleteFailException ex) {
				throw new InvocationTargetException(ex, ex.getMessage());
			}
			monitor.worked(1);

			// Step.7
			msg = "設定ファイルを保存しています...";
			monitor.subTask(msg);
			logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
			LocalModelManager mgr = LocalModelManager.getInstance();
			mgr.removeRoot(path);
			monitor.worked(1);

			// Step.8
			monitor.subTask("リフレッシュをしています...");
			//			new RefreshAction(vmgr).run();
			cmdmgr.addCommand(factory.createRemoteRefreshCommand());
			monitor.worked(1);

			monitor.done();
		}
	}
}
