/*
 *                 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 Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.lib.cvsclient.request;

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

import org.netbeans.lib.cvsclient.*;
import org.netbeans.lib.cvsclient.admin.*;
import org.netbeans.lib.cvsclient.command.*;
import org.netbeans.lib.cvsclient.file.*;

/**
 * @author Thomas Singer
 */
public final class Requests {

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

	public static void addArgumentRequest(String argument, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new ArgumentRequest(argument));
	}

	public static void addArgumentRequest(String argument, String value, IRequestSender requestSender) throws CommandAbortedException, IOException {
		addArgumentRequest(argument, requestSender);
		addArgumentRequest(value, requestSender);
	}

	public static void addArgumentRequests(Collection<? extends FsPath> fsPaths, IRequestSender requestSender) throws CommandAbortedException, IOException {
		for (final FsPath fsPath : fsPaths) {
			addArgumentRequest(fsPath, requestSender);
		}
	}

	public static void addArgumentRequest(FsPath fsPath, IRequestSender requestSender) throws CommandAbortedException, IOException {
		addArgumentRequest(FileUtils.toUnixPath(fsPath, true), requestSender);
	}

	public static void addMessageRequests(String message, IRequestSender requestSender) throws CommandAbortedException, IOException {
		addArgumentRequest("-m", requestSender);
		addMultilineArgumentRequests(message, requestSender);
	}

	public static void addMultilineArgumentRequests(String message, IRequestSender requestSender) throws CommandAbortedException, IOException {
		int lineStartIndex = 0;
		for (int newLineIndex = message.indexOf('\n', lineStartIndex); newLineIndex > 0;
		     lineStartIndex = newLineIndex + 1, newLineIndex = message.indexOf('\n', lineStartIndex)) {
			addMultilineArgumentRequest(message, lineStartIndex, newLineIndex, requestSender);
		}
		if (lineStartIndex == 0 || lineStartIndex != message.length()) {
			addMultilineArgumentRequest(message, lineStartIndex, message.length(), requestSender);
		}
	}

	public static void addLocalPathDirectoryRequest(ICvsFileSystem cvsFileSystem, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new LocalDirectoryRequest(cvsFileSystem.getAbsoluteRepositoryRootPath()));
	}

	public static void addLocalPathDirectoryRequest(String relativeRepositoryPath, ICvsFileSystem cvsFileSystem, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new LocalDirectoryRequest(cvsFileSystem.getAbsoluteRepositoryPath(relativeRepositoryPath)));
	}

	public static void addLocalPathDirectoryRequest(IAdminReader adminReader, ICvsFileSystem cvsFileSystem, IRequestSender requestSender) throws IOException {
		final String repositoryPath = cvsFileSystem.getAbsoluteRepositoryPathForDirectory(FsDirectoryPath.ROOT, adminReader);
		requestSender.sendRequest(new LocalDirectoryRequest(repositoryPath));
	}

	public static void addDirectoryRequest(FsDirectoryPath fsDirectory, IAdminReader adminReader, ICvsFileSystem cvsFileSystem, IRequestSender requestSender) throws IOException {
		final String relativeDirPath = FileUtils.toUnixPath(fsDirectory, true);
		final String repositoryPath = cvsFileSystem.getAbsoluteRepositoryPathForDirectory(fsDirectory, adminReader);
		requestSender.sendRequest(new DirectoryRequest(relativeDirPath, repositoryPath));
	}

	public static void addDirectoryStickyRequests(FsDirectoryPath fsDirectory, IAdminReader adminReader, ICvsFileSystem cvsFileSystem, IRequestSender requestSender) throws IOException, CommandAbortedException {
		addDirectoryRequest(fsDirectory, adminReader, cvsFileSystem, requestSender);
		if (adminReader.isStaticDirectory(fsDirectory)) {
			requestSender.sendRequest(StaticDirectoryRequest.INSTANCE);
		}
		addStickyRequest(adminReader.getStickyTagForDirectory(fsDirectory), requestSender);
	}

	public static void addStickyRequest(String tag, IRequestSender requestSender) throws IOException {
		if (tag == null) {
			return;
		}

		requestSender.sendRequest(new StickyRequest(tag));
	}

	public static void addModifiedRequest(FsFilePath fsFile, boolean binary, FilePermissions permissions, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new ModifiedRequest(fsFile, binary, permissions));
	}

	public static void addIsModifiedRequest(FsFilePath fsFile, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new IsModifiedRequest(fsFile));
	}

	public static void addUnchangedRequest(FsFilePath fsFile, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new UnchangedRequest(fsFile));
	}

	public static void addEntryRequest(Entry entry, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new EntryRequest(entry));
	}

	public static void addQuestionableRequest(FsFilePath fsFile, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new QuestionableRequest(fsFile));
	}

	public static void addNotifyRequest(FsFilePath fsFile, ILocalFileSystem localFileSystem, String command, String temporaryWatch, IRequestSender requestSender) throws IOException {
		final String path = localFileSystem.getFile(fsFile.getParent()).getAbsolutePath();
		requestSender.sendRequest(new NotifyRequest(fsFile, path, command, temporaryWatch));
	}

	public static void addKoptRequest(KeywordSubstitution keywordSubstMode, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new KoptRequest(keywordSubstMode));
	}

	public static void addCheckinTimeRequest(Date date, IRequestSender requestSender) throws IOException {
		requestSender.sendRequest(new CheckinTimeRequest(date));
	}

	// Utils ==================================================================

	private static void addMultilineArgumentRequest(String message, int lineStartIndex, int lineEndIndex, IRequestSender requestSender) throws CommandAbortedException, IOException {
		final String line = message.substring(lineStartIndex, lineEndIndex);
		if (lineStartIndex == 0) {
			addArgumentRequest(line, requestSender);
		}
		else {
			requestSender.sendRequest(new ArgumentxRequest(line));
		}
	}
}
