/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Thomas Singer. All Rights Reserved.
 */
package org.netbeans.lib.cvsclient.command.watch;

import java.io.*;
import java.util.*;

import org.netbeans.lib.cvsclient.*;
import org.netbeans.lib.cvsclient.command.*;
import org.netbeans.lib.cvsclient.event.*;
import org.netbeans.lib.cvsclient.file.*;
import org.netbeans.lib.cvsclient.progress.*;
import org.netbeans.lib.cvsclient.progress.sending.*;
import org.netbeans.lib.cvsclient.util.*;

/**
 * @author Thomas Singer
 */
public final class WatchCommand extends AbstractCommand {

	// Static =================================================================

	public static WatchCommand createWatchCommand(FsDirectoryPath fsDirectory, WatchMode watchMode, Watch watch) {
		return new WatchCommand(Collections.singleton(fsDirectory), watchMode, watch);
	}

	public static WatchCommand createWatchCommand(Collection<FsFilePath> fsFiles, WatchMode watchMode, Watch watch) {
		return new WatchCommand(fsFiles, watchMode, watch);
	}

	// Fields =================================================================

	private final Collection<? extends FsPath> fsPaths;
	private final WatchMode watchMode;
	private final Watch watch;

	// Setup ==================================================================

	private WatchCommand(Collection<? extends FsPath> fsPaths, WatchMode watchMode, Watch watch) {
		BugLog.assertTrue(fsPaths != null && fsPaths.size() > 0);
		BugLog.assertNotNull(watchMode);
		BugLog.assertNotNull(watch);

		this.fsPaths = fsPaths;
		this.watchMode = watchMode;
		this.watch = watch;
	}

	// Implemented ============================================================

	@Override
	public boolean execute(IRequestProcessor requestProcessor, IEventSender eventSender, ICvsListenerRegistry listenerRegistry, IClientEnvironment clientEnvironment,
	                       IProgressViewer progressViewer) throws CommandException {
		final ICvsFiles cvsFiles;
		try {
			cvsFiles = FileSystemScanner.scan(fsPaths, true, clientEnvironment);
		}
		catch (IOException ex) {
			throw new IOCommandException(ex);
		}

		final IRequestsProgressHandler requestsProgressHandler = new FileStateRequestsProgressHandler(new RangeProgressViewer(progressViewer, 0.0, 0.5), cvsFiles);
		return requestProcessor.communicateWithServer(new WatchRequestFactory(cvsFiles, fsPaths, watchMode, watch),
		                                              requestsProgressHandler, clientEnvironment, getGlobalOptions());
	}

	@Override
	public String getCvsCommandLine() {
		final StringBuilder cvsCommand = new StringBuilder("watch ");
		cvsCommand.append(watchMode.toString());
		cvsCommand.append(' ');

		if (watchMode.isWatchOptionAllowed()) {
			cvsCommand.append("-a ");
			cvsCommand.append(watch.toString());
			cvsCommand.append(' ');
		}
		CommandUtils.appendFileArguments(fsPaths, cvsCommand);
		return cvsCommand.toString();
	}
}
