package com.interpress_project.modernshare.client.view.wizard;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.io.FileUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.Wizard;

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.exceptions.CommandException;
import com.interpress_project.modernshare.client.controller.model.LocalModelManager;
import com.interpress_project.modernshare.client.controller.model.PropertyManager;
import com.interpress_project.modernshare.client.controller.model.RootStatus;
import com.interpress_project.modernshare.client.controller.model.SVNRoot;
import com.interpress_project.modernshare.client.events.LogEvent;
import com.interpress_project.modernshare.client.events.LogEventSource;
import com.interpress_project.modernshare.client.events.LogEventType;
import com.interpress_project.modernshare.client.view.ViewManager;
import com.interpress_project.modernshare.ipcommon.SystemBase;

public class Checkout2Wizard extends Wizard {
	private final ViewManager vmgr = ViewManager.getInstance();
	private final LogEventSource logEventSource = LogEventSource.getInstance();
	private final SVNCommandFactory factory = SVNCommandFactory.getInstance();
	private final SVNCommandManager cmdmgr = SVNCommandManager.getInstance();

	private CheckoutWelcomePage checkoutWelcomePage = new CheckoutWelcomePage();
	private CheckoutWizardPage2 checkoutWizardPage2 = new CheckoutWizardPage2();
	private CheckoutWizardPage3 checkoutWizardPage3 = new CheckoutWizardPage3();
	private CheckoutConfirmPage checkoutConfirmPage = new CheckoutConfirmPage();
	private SVNRoot root;

	/**
	 * CheckoutWizard
	 * @param list
	 */
	public Checkout2Wizard(SVNRoot root) {
		addPage(checkoutWelcomePage);
		addPage(checkoutWizardPage2);
		addPage(checkoutWizardPage3);
		addPage(checkoutConfirmPage);

		setNeedsProgressMonitor(true);
		setWindowTitle("ホットショット・フォルダ - チェックアウト・ウィザード");

		this.root = root;
	}

	/**
	 * performFinish
	 */
	@Override
	public boolean performFinish() {
		/**
		 * スレッドの定義
		 */
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
				checkout(monitor);
			}
		};

		/**
		 * 上記スレッドの実行
		 */
		try {
			logEventSource.fireEvent(new LogEvent(this, LogEventType.CLEAR));

			getContainer().run(true, true, op);
		}
		catch (InvocationTargetException ex) {
			logEventSource.fireEvent(new LogEvent(this, ex.getLocalizedMessage(), LogEventType.ERROR, ex));
			vmgr.getDialogManager().createErrorMessageDialog(ex.getMessage());
			return false;
		}
		catch (InterruptedException ex) {
		}
		return true;
	}

	/**
	 * checkout
	 * @param monitor
	 * @throws InvocationTargetException
	 */
	private void checkout(IProgressMonitor monitor) throws InvocationTargetException {
		String path = checkoutWizardPage2.getPath();
		RootStatus status = checkoutWizardPage3.getStatus();
		boolean bPc2host = checkoutWizardPage3.getPc2host();
		String msg = null;

		PropertyManager propmgr = PropertyManager.getInstance();

		monitor.beginTask("", 5);

		// Step. 1
		msg = "ホットショット・フォルダとして作成するフォルダの内容をチェックします。お待ちください...";
		monitor.subTask(msg);
		logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));

		File targetfile = new File(path);
		String[] list = targetfile.list();
		if (list.length > 0) {
			boolean bAnswer = vmgr.getDialogManager().createYesNoMessageDialog("ホットショット・フォルダの確認",
			  "指定されたフォルダ" + path + "には既にファイルが存在していします。全てのファイルを削除してよろしいですか?");
			if (bAnswer) {
				msg = "フォルダからファイルを削除しています...";
				monitor.subTask(msg);
				logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
				try {
					FileUtils.cleanDirectory(targetfile);
				}
				catch (IOException ex) {
					throw new InvocationTargetException(ex, ex.getMessage());
				}
			}
			else {
				msg = "ファイルが存在するフォルダを、ホットショット・フォルダとして作成することはできません。";
				logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.ERROR));
				vmgr.getDialogManager().createInformationMessageDialog("フォルダの確認", msg);
				return;
			}
		}
		monitor.worked(1);

		SystemBase.getInstance().gc();

		// Step.2 
		monitor.subTask("チェックアウトを行っています...");

		try {
			cmdmgr.execCommand(factory.createCheckoutCommand(path, root, status, bPc2host));
			monitor.worked(1);
		}
		catch (CommandException ex) {
			throw new InvocationTargetException(ex, ex.getMessage());
		}
		// Step.3
		msg = "Readmeファイルを作成しています...";
		monitor.subTask(msg);
		logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
		if (bPc2host) {
			new NoticeFile(path, propmgr.getIgnoreFilterList(), false).create();
		}
		else {
			new NoticeFile(path, propmgr.getIgnoreFilterList(), true).create();
		}
		monitor.worked(1);

		// Step.4
		msg = "設定ファイルを保存しています...";
		monitor.subTask(msg);
		logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
		LocalModelManager limgr = LocalModelManager.getInstance();
		limgr.addRoot(path, root.getName(), status, bPc2host);
		monitor.worked(1);

		// Step.5
		msg = "ローカルPCをリフレッシュしています...";
		monitor.subTask(msg);
		logEventSource.fireEvent(new LogEvent(this, msg, LogEventType.INFO));
		//		new LocalRefreshAction(vmgr).run();
		cmdmgr.addCommand(factory.createLocalRefreshCommand());
		monitor.worked(1);

		monitor.done();
	}
}
