/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core.util;


import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.Session;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;

/**
 * Unsorted static helper-methods 
 */
public class Util {
	
	/**
	 * Return the last segment of the given path
	 * @param path
	 * @return String
	 */
	public static String getLastSegment(String path) {
		int index = path.lastIndexOf(Session.SERVER_SEPARATOR);
		if (index == -1) {
			return path;
		}
		if (index == path.length() - 1) {
			return getLastSegment(path.substring(0, index));
		}
		return path.substring(index + 1);
		
	}
	
	/**
	 * Return the given path with the last segment removed
	 * @param path
	 * @return String
	 */
	public static String removeLastSegment(String path) {
		int index = path.lastIndexOf(Session.SERVER_SEPARATOR);
		if (index == -1)
			return ""; //$NON-NLS-1$
		else
			return path.substring(0, index);

	}
	/**
	 * Return the path without a trailing /
	 * @param path
	 * @return String
	 */
	public static String asPath(String path) {
		if (path.endsWith(Session.SERVER_SEPARATOR)) {
			return path.substring(0, path.length() - Session.SERVER_SEPARATOR.length());
		}
		return path;
	}

	/**
	 * Get the extention of the path of resource relative to the path of root
	 * 
	 * @throws CVSException
	 *             if root is not a root-folder of resource
	 */
	public static String getRelativePath(String rootName, String resourceName) 
		throws CVSException {

		if (!resourceName.startsWith(rootName) || rootName.length() > resourceName.length()) {
			throw new CVSException(CVSMessages.Util_Internal_error__resource_does_not_start_with_root_3); 
		}
		
		// Otherwise we would get an ArrayOutOfBoundException
		// in case of two equal Resources
		if (rootName.length() == resourceName.length()) {
			return ""; //$NON-NLS-1$
		}
		
		// Remove leading slash if there is one
		String result = resourceName.substring(rootName.length());
		if (result.startsWith("/")) { //$NON-NLS-1$
			result = result.substring(1);
		}
		return result;
	}
	
	/**
	 * Append the prefix and suffix to form a valid CVS path.
	 */
	public static String appendPath(String prefix, String suffix) {
		if (prefix.length() == 0 || prefix.equals(Session.CURRENT_LOCAL_FOLDER)) {
			return suffix;
		} else if (prefix.endsWith(Session.SERVER_SEPARATOR)) {
			if (suffix.startsWith(Session.SERVER_SEPARATOR))
				return prefix + suffix.substring(1);
			else
				return prefix + suffix;
		} else if (suffix.startsWith(Session.SERVER_SEPARATOR))
			return prefix + suffix;
		else
			return prefix + Session.SERVER_SEPARATOR + suffix;
	}

	public static void logError(String message, Throwable throwable) {
		CVSProviderPlugin.log(IStatus.ERROR, message, throwable);
	}

	/**
	 * If the number of segments in the relative path of <code>resource</code> to <code>root</code> is 
	 * greater than <code>split</code> then the returned path is truncated to <code>split</code> number
	 * of segments and '...' is shown as the first segment of the path.
	 */
	public static String toTruncatedPath(ICVSResource resource, ICVSFolder root, int split) {
		try {
			String stringPath = resource.getRelativePath(root);
			if (stringPath.equals(Session.CURRENT_LOCAL_FOLDER)) {
				return resource.getName();
			}
			String truncatedPath = toTruncatedPath(stringPath, split);
			return truncatedPath;
		} catch(CVSException e) {
			return resource.getName();
		}
	}

	public static String toTruncatedPath(String stringPath, int split) {
		// Search backwards until split separators are found
		int count = 0;
		int index = stringPath.length();
		while (count++ < split && index != -1) {
			index = stringPath.lastIndexOf(Session.SERVER_SEPARATOR, index - 1);
		}
		if (index == -1) {
			return stringPath;
		} else {
			return NLS.bind(CVSMessages.Util_truncatedPath, new String[] { stringPath.substring(index) }); 
		}
	}
	
	/**
	 * Helper method that will time out when making a socket connection.
	 * This is required because there is no way to provide a timeout value
	 * when creating a socket and in some instances, they don't seem to
	 * timeout at all.
	 */
	public static Socket createSocket(final String host, final int port, IProgressMonitor monitor) throws UnknownHostException, IOException {
		int timeout = CVSProviderPlugin.getPlugin().getTimeout();
		if (timeout == 0) timeout = CVSProviderPlugin.DEFAULT_TIMEOUT;
		ResponsiveSocketFactory factory = new ResponsiveSocketFactory(monitor, timeout);
		return factory.createSocket(host, port);
	}
	
	/**
	 * Helper method that will time out when running an external command.
	 * This is required because there is no way to provide a timeout value
	 * when executing an external command and in some instances, they don't seem to
	 * timeout at all.
	 */
	public static Process createProcess(final String[] command, IProgressMonitor monitor) throws IOException {
		
		// Start a thread to execute the command and get a handle to the process
		final Process[] process = new Process[] { null };
		final Exception[] exception = new Exception[] {null };
		final Thread thread = new Thread(() -> {
			try {
				Process newProcess = Runtime.getRuntime().exec(command);
				synchronized (process) {
					if (Thread.interrupted()) {
						// we we're either cancelled or timed out so just destroy the process
						newProcess.destroy();
					} else {
						process[0] = newProcess;
					}
				}
			} catch (IOException e) {
				exception[0] = e;
			}
		});
		thread.start();
		
		// Wait the appropriate number of seconds
		int timeout = CVSProviderPlugin.getPlugin().getTimeout();
		if (timeout == 0) timeout = CVSProviderPlugin.DEFAULT_TIMEOUT;
		for (int i = 0; i < timeout; i++) {
			try {
				// wait for the thread to complete or 1 second, which ever comes first
				thread.join(1000);
			} catch (InterruptedException e) {
				// I think this means the thread was interupted but not necessarily timed out
				// so we don't need to do anything
			}
			synchronized (process) {
				// if the user cancelled, clean up before preempting the operation
				if (monitor.isCanceled()) {
					if (thread.isAlive()) {
						thread.interrupt();
					}
					if (process[0] != null) {
						process[0].destroy();
					}
					// this method will throw the proper exception
					Policy.checkCanceled(monitor);
				}
			}
		}
		// If the thread is still running (i.e. we timed out) signal that it is too late
		synchronized (process) {
			if (thread.isAlive()) {
				thread.interrupt();
			}
		}
		if (exception[0] != null) {
			throw (IOException)exception[0];
		}
		if (process[0] == null) {
			throw new InterruptedIOException(NLS.bind(CVSMessages.Util_processTimeout, new String[] { command[0] })); 
		}
		return process[0];
	}
	
	public static String[] parseIntoSubstrings(String string, String delimiter) {
		List result = new ArrayList();
		int start = 0;
		int index = string.indexOf(delimiter);
		String next;
		while (index != -1) {
			next = string.substring(start, index);
			result.add(next);
			start = index + 1;
			index = string.indexOf(delimiter, start);
		}
		if (start >= string.length()) {
			next = "";//$NON-NLS-1$
		} else {
			next = string.substring(start);
		}
		result.add(next);
		return (String[]) result.toArray(new String[result.size()]);
	}
	
	/**
	 * Return the substring at the given index (starting at 0) where each
	 * element is delimited by the provided delimiter.
	 * 
	 * @param bytes
	 * @param delimiter
	 * @param index
	 * @param includeRest
	 * @return String
	 */
	public static String getSubstring(byte[] bytes, byte delimiter, int index, boolean includeRest) {
		byte[] bytesForSlot = getBytesForSlot(bytes, delimiter, index, includeRest);
		if (bytesForSlot == null) {
			return null;
		}
		return new String(bytesForSlot);
	}
	
	/**
	 * Return the offset the the Nth delimeter from the given start index.
	 * @param bytes
	 * @param delimiter
	 * @param start
	 * @param n
	 * @return int
	 */
	public static int getOffsetOfDelimeter(byte[] bytes, byte delimiter, int start, int n) {
		int count = 0;
		for (int i = start; i < bytes.length; i++) {
			if (bytes[i] == delimiter) count++;
			if (count == n) return i;
		}
		// the Nth delimeter was not found
		return -1;
	}
	
	/**
	 * Method getBytesForSlot.
	 * @param syncBytes
	 * @param SEPARATOR_BYTE
	 * @param i
	 * @param b
	 * @return byte[]
	 */
	public static byte[] getBytesForSlot(byte[] bytes, byte delimiter, int index, boolean includeRest) {
		// Find the starting index
		int start;
		if (index == 0) {
			// make start -1 so that end determination will start at offset 0.
			start = -1;
		} else {
			start = getOffsetOfDelimeter(bytes, delimiter, 0, index);
			if (start == -1) return null;
		}
		// Find the ending index
		int end = getOffsetOfDelimeter(bytes, delimiter, start + 1, 1);
		// Calculate the length
		int length;
		if (end == -1 || includeRest) {
			length = bytes.length - start - 1;
		} else {
			length = end - start - 1;
		}
		byte[] result = new byte[length];
		System.arraycopy(bytes, start + 1, result, 0, length);
		return result;
	}
	
	/**
	 * Method equals.
	 * @param syncBytes
	 * @param oldBytes
	 * @return boolean
	 */
	public static boolean equals(byte[] syncBytes, byte[] oldBytes) {
		if (syncBytes == null || oldBytes == null) return syncBytes == oldBytes;
		if (syncBytes.length != oldBytes.length) return false;
		for (int i = 0; i < oldBytes.length; i++) {
			if (oldBytes[i] != syncBytes[i]) return false;
		}
		return true;
	}
	
	/**
	 * Workaround a CVS bug where a CVS Folder with no immediately contained files has an incorrect
	 * Tag type stored in the TAG file.  In this case, the tag type is always BRANCH (Tv1)
	 * 
	 * The fix is for folders with no files, use the tag type for the containing project.  Since projects almost
	 * always have files the TAG file is usually correct.
	 * 
	 * For the case where the folder tag name does not match the project tag name we can not do much so we just
	 * return the folder tag which will currently always be a branch.
	 * 
	 * @param resource The IResource being tested.  Can not be null.
	 * @param tag The CVSTag as reported by CVS for the IResource.  May be null.
	 * @return CVSTag The corrected tag for the resource.  May be null.
	 */
	public static CVSTag getAccurateFolderTag(IResource resource, CVSTag tag) {

		// Determine if the folder contains files as immediate children.
		if (resource.getType() != IResource.FOLDER) {
			return tag;
		}

		IResource[] members = null;
		try {
			members = ((IFolder) resource).members();
		} catch (CoreException e1) {
			return tag;
		}
		
		for (IResource member : members) {
			if (member.getType() == IResource.FILE) {
				return tag;
			}
		}
	
		// Folder contains no files so this may not really be a branch.
		// Make the type the same as the project tag type if both are the same tag name.
		IProject project = resource.getProject();
		if (project == null) {
			return tag;
		}
		
		ICVSFolder projectFolder = CVSWorkspaceRoot.getCVSFolderFor(project);
		FolderSyncInfo projectSyncInfo;
		try {
			projectSyncInfo = projectFolder.getFolderSyncInfo();
		} catch (CVSException e) {
			return tag;
		}
		
		if (projectSyncInfo == null) {
			return tag;
		}
		
		CVSTag projectTag = projectSyncInfo.getTag();
								
		if (projectTag != null && projectTag.getName().equals(tag.getName())) {
			return projectTag;
		} else {
			return tag;
		}
	}	
	
	/**
	 * Workaround for CVS "bug" where CVS ENTRIES file does not contain correct
	 * Branch vs. Version info.  Entries files always record a Tv1 so all entries would
	 * appear as branches.
	 * 	
	 * By comparing the revision number to the tag name
	 * you can determine if the tag is a branch or version.
	 * 
	 * @param cvsResource the resource to test.  Must nut be null.
	 * @return the correct cVSTag.  May be null.
	 */
	public static CVSTag getAccurateFileTag(ICVSResource cvsResource) throws CVSException {

		CVSTag tag = null;
		ResourceSyncInfo info = cvsResource.getSyncInfo();
		if(info != null) {
			tag = info.getTag();
		}

		FolderSyncInfo parentInfo = cvsResource.getParent().getFolderSyncInfo();
		CVSTag parentTag = null;
		if(parentInfo != null) {
			parentTag = parentInfo.getTag();
		}

		if(tag != null) {
			if(tag.getName().equals(info.getRevision())) {
				tag = new CVSTag(tag.getName(), CVSTag.VERSION);
			} else if(parentTag != null){
				tag = new CVSTag(tag.getName(), parentTag.getType());
			}
		}
		
		return tag;						
	}

	/**
	 * Workaround for CVS "bug" where CVS ENTRIES file does not contain correct
	 * Branch vs. Version info.  Entries files always record a Tv1 so all entries would
	 * appear as branches.
	 * 	
	 * By comparing the revision number to the tag name and to the existing tags
	 * you can determine if the tag is a branch or version.
	 * 
	 * @param cvsResource the resource to test.  Must nut be null.
	 * @return the correct cVSTag.  May be null.
	 */
	public static CVSTag getAccurateFileTag(ICVSResource cvsResource, CVSTag[] existing) throws CVSException {
		List tags= Arrays.asList(existing);
		CVSTag tag = null;
		ResourceSyncInfo info = cvsResource.getSyncInfo();
		if(info != null) {
			tag = info.getTag();
		}

		FolderSyncInfo parentInfo = cvsResource.getParent().getFolderSyncInfo();
		CVSTag parentTag = null;
		if(parentInfo != null) {
			parentTag = parentInfo.getTag();
		}

		if(tag != null) {
			if(tag.getName().equals(info.getRevision())) {
				tag = new CVSTag(tag.getName(), CVSTag.VERSION);
			} else if(parentTag != null){
				tag = new CVSTag(tag.getName(), parentTag.getType());
			} else if (!tags.contains(tag)) {
				if (!tags.contains(tag)) {
					CVSTag newTag= new CVSTag(tag.getName(), CVSTag.VERSION);
					if (tags.contains(newTag)) {
						tag = newTag;
					}
				}
			}
		}
		return tag;
	}
	
	/**
	 * Return the fullest path that we can obtain for the given resource
	 * @param resource
	 * @return
	 */
	public static String getFullestPath(ICVSResource resource) {
		IResource local = resource.getIResource();
		if (local != null) {
			return local.getFullPath().toString();
		}
		try {
			String remotePath = resource.getRepositoryRelativePath();
			if (remotePath != null) {
				return remotePath;
			}
		} catch (CVSException e) {
			// Ignore and try the next method;
		}
		return resource.getName();
	}
	
	public static String getVariablePattern(String pattern, String variableName) {
		return "(" + variableName + ":" + pattern + ":" + variableName + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}

	/**
	 * @param localRevision
	 * @return
	 */
	public static int[] convertToDigits(String localRevision) {
		try {
			String digitStrings[] = localRevision.split("\\."); //$NON-NLS-1$
			int[] digits = new int[digitStrings.length];
			for (int i = 0; i < digitStrings.length; i++) {
				String digitString = digitStrings[i];
				digits[i] = Integer.parseInt(digitString);
			}
			return digits;
		} catch (NumberFormatException e) {
			CVSProviderPlugin.log(CVSException.wrapException(e));
			return new int[0];
		}
	}

	public static String toTruncatedPath(ICVSStorage file, ICVSFolder localRoot, int i) {
		if (file instanceof ICVSResource) {
			return toTruncatedPath((ICVSResource)file, localRoot, i);
		}
		return file.getName();
	}
	
	/**
	 * If the status/log returns that the file is in the Attic, then remove the
	 * Attic segment. This is because files added to a branch that are not in
	 * the main trunk (HEAD) are added to the Attic but cvs does magic on
	 * update to put them in the correct location.
	 * (e.g. /project/Attic/file.txt -&gt; /project/file.txt)
	 */ 
	public static String removeAtticSegment(String path) {
		int lastSeparator = path.lastIndexOf(Session.SERVER_SEPARATOR);
		if (lastSeparator == -1) return path;
		int secondLastSeparator = path.lastIndexOf(Session.SERVER_SEPARATOR, lastSeparator - 1);
		if (secondLastSeparator == -1) return path;
		String secondLastSegment = path.substring(secondLastSeparator + 1, lastSeparator);
		if (secondLastSegment.equals("Attic")) { //$NON-NLS-1$
			return path.substring(0, secondLastSeparator) + path.substring(lastSeparator);
		}
		return path;
	}
	
	/**
	 * Flatten the text in the multiline comment
	 */
	public static String flattenText(String string) {
		StringBuilder buffer = new StringBuilder(string.length() + 20);
		boolean skipAdjacentLineSeparator = true;
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			if (c == '\r' || c == '\n') {
				if (!skipAdjacentLineSeparator)
					buffer.append(Session.SERVER_SEPARATOR); 
				skipAdjacentLineSeparator = true;
			} else {
				buffer.append(c);
				skipAdjacentLineSeparator = false;
			}
		}
		return buffer.toString();
	}
}
