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

import java.io.File;

import com.interpress_project.modernshare.client.controller.command.exceptions.CommandException;
import com.interpress_project.modernshare.client.controller.delegate.LocalSVNManager;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.ConnectionFailException;
import com.interpress_project.modernshare.client.controller.delegate.exceptions.InternalFailException;
import com.interpress_project.modernshare.client.controller.model.LocalRoot;
import com.interpress_project.modernshare.client.events.LogEvent;
import com.interpress_project.modernshare.client.events.LogEventType;
import com.interpress_project.modernshare.ipcommon.SystemBase;

public class SyncLocalWithRemoteCommand extends ISVNCommand {
	private final SystemBase sb = SystemBase.getInstance();
	private final LocalSVNManager svnmgr = LocalSVNManager.getInstance();
	private final SVNCommandManager cmdmgr = SVNCommandManager.getInstance();
	private final SVNCommandFactory factory = SVNCommandFactory.getInstance();
	private File rootpath;
	private LocalRoot localRoot;

	/**
	 * SyncRemoteCommand
	 * @param path
	 */
	public SyncLocalWithRemoteCommand(LocalRoot localRoot) {
		super();

		this.rootpath = new File(localRoot.getAbsolutePath());
		this.localRoot = localRoot;
	}

	/**
	 * execute
	 */
	public void execute() throws CommandException {
		logEventSource.fireEvent(new LogEvent(this, "データセンタに格納されたデータで" + rootpath + "を更新します...", LogEventType.INFO));

		localRoot.stopFsWatcher(); // 更新中はファイルシステム監視を停止する
		try {
			/**
			 * Main process
			 */
			_execute();

			/**
			 * Refresh local views.
			 */
			cmdmgr.addCommand(factory.createLocalRefreshCommand());
		}
		finally {
			localRoot.startFsWatcher();
			sb.getLogger().debug(sb.gc()); // Gabage collection.
		}
		logEventSource.fireEvent(new LogEvent(this, rootpath + "への更新処理が終了しました。", LogEventType.INFO));
	}

	/**
	 * _execute
	 * @throws CommandException
	 */
	public void _execute() throws CommandException {
		sb.getLogger().debug("Enter SyncLocalWithRemoteCommand()._execute");

		// Make a connection.
		try {
			svnmgr.connect();
		}
		catch (ConnectionFailException ex) {
			throw new CommandException(ex);
		}

		// SVN cleanup
		try {
			svnmgr.cleanupFiles(rootpath);
		}
		catch (InternalFailException ex) {
			sb.getLogger().warn("SVNクリーンアップ処理が失敗しました。処理を継続します。", ex);
			// Fall throught...
		}

		try {
			svnmgr.syncLocalFilesWithRemote(rootpath);
		}
		catch (InternalFailException ex) {
			throw new CommandException(ex);
		}
		sb.getLogger().debug("Leave SyncLocalWithRemoteCommand()._execute");
	}
}
