//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.utils;

import java.net.URI;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.CommonPlugin;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.util.StringTokenizer;

/**
 * A helper class for manuipulating strings.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 */
public class StrUtil {
	public static final String EMPTY_STRING = ""; //$NON-NLS-1$

	public static final String TAB = "\t"; //$NON-NLS-1$

	private static final String REGEXP_ANY_SPECIAL_CHARS = "(`|~|!|@|#|\\$|%|\\^|&|\\*|\\(|\\)|\\+|=|\\[|\\]|\\||\\:|\"|<|>|\\?|/|'|\\s|\\\\)+"; //$NON-NLS-1$

	private static final String REGEXP_INVALID_PUBLISHED_PATH_CHARS = "(\\[|#|\\*|\\?|\"|<|>|\\||!|%|/|\\])+"; //$NON-NLS-1$

	private static final String REGEXP_INVALID_PUBLISHED_PATH_CHARS_LINUX = "(\\[|#|\\*|\\?|\"|<|>|\\||!|%|\\])+"; //$NON-NLS-1$

	private static final String REGEXP_INVALID_FILENAME_CHARS = "(\\[|#|/|\\\\|\\:|\\*|\\?|\"|<|>|\\||\\]|\\s)+"; //$NON-NLS-1$

	private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	public static final String LINE_FEED = System.getProperty("line.separator"); //$NON-NLS-1$

	public static final String ESCAPED_LF = "&#xA;"; //$NON-NLS-1$

	public static final String ESCAPED_CR = "&#xD;"; //$NON-NLS-1$

	public static final String ESCAPED_LINE_FEED = LINE_FEED.replace(
			"\n", ESCAPED_LF).replace("\r", ESCAPED_CR); //$NON-NLS-1$ //$NON-NLS-2$

	public static final String LINE_FEED_REGEX = LINE_FEED.replaceAll(
			"\\\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$

	public static final String ESCAPED_LINE_FEED_REGEX = ESCAPED_LINE_FEED;

	public static final String HTML_BREAK = "<br/>";//$NON-NLS-1$

	public static final String HTML_COPY = "&copy;";//$NON-NLS-1$

	public static final String HTML_EURO = "&euro;";//$NON-NLS-1$ 	

	public static final String HTML_REG = "&reg;";//$NON-NLS-1$ 

	public static final String HTML_TRADEMARK = "&trade;";//$NON-NLS-1$

	/**
	 * Private constructor to prevent this class from being instantiated. All
	 * methods in this class should be static.
	 */
	private StrUtil() {
	}

	/**
	 * Tests for null string.
	 * <p>
	 * A null string is defined as one that has an empty reference or has zero
	 * length.
	 * 
	 * @param str
	 *            a string
	 * @return <code>true</code> if the given string is a null string
	 */
	public static boolean isNull(String str) {
		return str == null || str.length() == 0;
	}

	/**
	 * Tests for blank string.
	 * <p>
	 * A blank string is defined as one that has an empty reference or has zero
	 * length after the leading and trailing space characters are trimmed.
	 * 
	 * @param str
	 *            a string
	 * @return <code>true</code> if the given string is a blank string
	 */
	public static boolean isBlank(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * Removes the leading and trailing space characters from a string.
	 * 
	 * @param str
	 *            a string
	 * @return a string with no leading and trailing space characters
	 */
	public static String trim(String str) {
		return str == null ? null : str.trim();
	}

	/**
	 * Removes whitespace characters (TAB, CR, LF and SPACE) from a string.
	 * 
	 * @param str
	 *            a string
	 * @return a string with whitespace characters removed
	 */
	public static String removeWhiteSpaceChars(String str) {
		int len = (str == null) ? 0 : str.length();
		for (int i = 0; i < len; i++) {
			switch (str.charAt(i)) {
			case '\t':
			case '\r':
			case '\n':
			case ' ':
				break;
			default:
				return str;
			}
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * Removes CR, LF from a string.
	 * 
	 * @param str
	 *            a string
	 * @return a string with CR, LF removed
	 */
	public static String removeNewlines(String str) {
		StringBuffer sb = new StringBuffer();
		int len = (str == null) ? 0 : str.length();
		for (int i = 0; i < len; i++) {
			char c = str.charAt(i);
			switch (c) {
			case '\r':
			case '\n':
				break;
			default:
				sb.append(c);
			}
		}
		return sb.toString(); 
	}

	/**
	 * Splits a string into an array of string tokens.
	 * 
	 * @param str
	 *            a string
	 * @param sep
	 *            a string containing the string separators
	 * @param count
	 *            the desired number of string tokens
	 * @return an array of string tokens
	 */
	public static String[] split(String str, String sep, int count) {
		if (str == null || count == 0 || count < -1) {
			return null;
		}

		StringTokenizer tokenizer = new StringTokenizer(str, sep,
				count == -1 ? false : true);

		if (count == -1) {
			count = tokenizer.countTokens();
		}

		String[] result = new String[count];
		int i = 0;
		while (tokenizer.hasMoreTokens()) {
			String t = tokenizer.nextToken();
			if (i < count) {
				if ((t.length() == 1) && (sep.indexOf(t) != -1)) {
					continue;
				}
				result[i++] = t;
			} else {
				result[count - 1] += t;
			}
		}
		return result;
	}

	/**
	 * Splits a string into an array of string tokens.
	 * 
	 * @param str
	 *            a string
	 * @param sep
	 *            a string containing the string separators
	 * @return an array of string tokens
	 */
	public static String[] split(String str, String sep) {
		return split(str, sep, -1);
	}

	/**
	 * Replaces a substring within a string with another substring.
	 * <p>
	 * Note: Only the first occurrence of the substring will be replaced.
	 * 
	 * @param str
	 *            a string
	 * @param src
	 *            the substring to replace
	 * @param tgt
	 *            the substring to use for the replacement
	 * @return a string with the first substring replaced
	 * 
	 * TODO: Review implementation. Call String.replaceFirst() instead?
	 */
	public static String replace(String str, String src, String tgt) {
		if ((str == null || str.length() == 0)
				|| (src == null || src.length() == 0)) {
			return str;
		}

		String tmpStr = str;
		int index;
		while ((index = tmpStr.indexOf(src)) != -1) {
			tmpStr = tmpStr.substring(0, index) + tgt
					+ tmpStr.substring(index + src.length());
		}
		return tmpStr;
	}

	/**
	 * Returns the integer value of a string.
	 * 
	 * @param str
	 *            a string
	 * @param defaultValue
	 *            a default integer value for the string
	 * @return the integer value of the given string
	 */
	public static int getIntValue(String str, int defaultValue) {
		if (StrUtil.isBlank(str)) {
			return defaultValue;
		}

		try {
			return Integer.parseInt(str);
		} catch (NumberFormatException e) {
			return defaultValue;
		}
	}

	/**
	 * Returns an array of bytes representing the UTF-8 encoding of a string.
	 * 
	 * @param str
	 *            a string
	 * @return a byte array containing the UTF-8 encoding of the given string
	 */
	public static byte[] getUTF8Bytes(String str) {
		char[] c = str.toCharArray();
		int len = c.length;
		int count = 0;
		for (int i = 0; i < len; i++) {
			int ch = c[i];
			if (ch <= 0x7f) {
				count++;
			} else if (ch <= 0x7ff) {
				count += 2;
			} else {
				count += 3;
			}
		}

		byte[] b = new byte[count];
		int off = 0;
		for (int i = 0; i < len; i++) {
			int ch = c[i];
			if (ch <= 0x7f) {
				b[off++] = (byte) ch;
			} else if (ch <= 0x7ff) {
				b[off++] = (byte) ((ch >> 6) | 0xc0);
				b[off++] = (byte) ((ch & 0x3f) | 0x80);
			} else {
				b[off++] = (byte) ((ch >> 12) | 0xe0);
				b[off++] = (byte) (((ch >> 6) & 0x3f) | 0x80);
				b[off++] = (byte) ((ch & 0x3f) | 0x80);
			}
		}
		return b;
	}

	/**
	 * Returns the hexidecimal character representation for an integer.
	 * 
	 * @param value
	 *            an integer
	 * @return the hexidecimal representation
	 */
	private static char toHex(int value) {
		return HEX_DIGITS[(value & 0xF)];
	}

	/**
	 * Returns the escaped Unicode representation of a string.
	 * 
	 * @param str
	 *            a string
	 * @param skipASCII
	 *            if <code>true</code>, avoid escaping the ASCII characters
	 * @return the escaped Unicode representation of the given string
	 */
	public static String toEscapedUnicode(String str, boolean skipASCII) {
		int len = str.length();
		StringBuffer result = new StringBuffer(len * 2);

		for (int i = 0; i < len; i++) {
			char ch = str.charAt(i);

			if (skipASCII && ch < 0x007E) {
				result.append(ch);
			} else {
				result.append("\\u"); //$NON-NLS-1$
				result.append(toHex((ch >> 12) & 0xF));
				result.append(toHex((ch >> 8) & 0xF));
				result.append(toHex((ch >> 4) & 0xF));
				result.append(toHex(ch & 0xF));
			}
		}

		return result.toString();
	}

	/**
	 * Returns the escaped HTML representation of a string.
	 * 
	 * @param html
	 *            a HTML string
	 * @return the escaped Unicode representation of the given HTML string
	 */
	public static String getEscapedHTML(String html) {
		if (html == null || html.length() == 0) {
			return ""; //$NON-NLS-1$
		}

		StringBuffer result = new StringBuffer();
		int length = html.length();
		for (int i = 0; i < length; i++) {
			char ch = html.charAt(i);
			switch (ch) {
			case '%':
				if (i + 4 < length) {
					String hexStr = html.substring(i + 1, i + 5);
					try {
						int codePoint = Integer.parseInt(hexStr, 16);
						char[] c = UCharacter.toChars(codePoint);
						result.append(c);
						i += 4;
						break;
					} catch (Exception e) {
						// wasn't a valid hex string..
						// fall through to the result.append(ch)
						CommonPlugin.getDefault().getLogger().logError(e);
					}
				}
				result.append(ch);
				break;
			case '\u00a9':
				result.append(HTML_COPY);
				break;
			case '\u00ae':
				result.append(HTML_REG);
				break;
			case '\u20ac':
				result.append(HTML_EURO);
				break;
			case '\u2122':
				result.append(HTML_TRADEMARK);
				break;
			default:
				result.append(ch);
				break;
			}
		}
		return result.toString();
	}

	/**
	 * Returns the plain text from HTML text.
	 * <p>
	 * Note: All HTML tags will be stripped.
	 * 
	 * @param html
	 *            the HTML text.
	 * @return the plain text representation of the given HTML text
	 */
	public static String getPlainText(String html) {
		if (html == null) {
			return ""; //$NON-NLS-1$
		}

		final Pattern p_plaintext_filter = Pattern.compile(
				"<[^>]*?>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
		final Pattern p_plaintext_filter2 = Pattern.compile(
				"&.{1,5}[^;];", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
		final Pattern p_plaintext_filter3 = Pattern.compile(
				"\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

		String result = html.replaceAll(p_plaintext_filter.pattern(), " ") //$NON-NLS-1$
				.replaceAll(p_plaintext_filter2.pattern(), " ") //$NON-NLS-1$
				.replaceAll(p_plaintext_filter3.pattern(), " "); //$NON-NLS-1$
		return result;
	}

	/**
	 * Converts a string into a valid file name.
	 * 
	 * @param str
	 *            a string
	 * @return a valid file name derived from the given string
	 */
	public static String makeValidFileName(String str) {
		if (str == null) {
			return ""; //$NON-NLS-1$
		}
		return getPlainText(str)
				.replaceAll(REGEXP_INVALID_FILENAME_CHARS, " ").trim(); //$NON-NLS-1$ 
	}

	public static String removeSpecialCharacters(String str) {
		if (str == null) {
			return ""; //$NON-NLS-1$
		}
		return getPlainText(str)
				.replaceAll(REGEXP_ANY_SPECIAL_CHARS, " ").trim(); //$NON-NLS-1$ 
	}

	/**
	 * Returns true if the path does not contain any invalid filename
	 * characters.
	 * 
	 * @param path
	 *            the file path
	 * @return <code>true</code> if the given path contains only valid
	 *         filename characters
	 */
	public static boolean isValidPublishPath(String path) {
		// return path.replaceAll(invalidPublishPathCharsRegExp,
		// "").equals(path);

		if (Platform.getOS().equals(Platform.WS_WIN32)) {
			return path
					.replaceAll(REGEXP_INVALID_PUBLISHED_PATH_CHARS, "").equals(path); //$NON-NLS-1$
		}

		// else default to Linux
		return path
				.replaceAll(REGEXP_INVALID_PUBLISHED_PATH_CHARS_LINUX, "").equals(path); //$NON-NLS-1$
	}

	/**
	 * Returns the lower-case of str unless the current locale is German
	 * 
	 * @param str
	 * @return
	 */
	public static String toLower(String str) {
		if (Platform.getNL().startsWith("de")) { //$NON-NLS-1$
			return str;
		}
		return str.toLowerCase();
	}

	/**
	 * escape the " and '
	 * 
	 * @param str
	 * @return
	 */
	public static String escape(String str) {
		return str.replaceAll("'", "\\\\\'").replaceAll("\"", "\\\\\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}

	/**
	 * Converts a <code>List</code> to an String array.
	 * 
	 * @param list
	 *            a <code>List</code>
	 * @return a String array
	 */
	public static String[] convertListToStrArray(List list) {
		if (list != null) {
			int cnt = list.size();
			String[] strArray = new String[cnt];

			for (int i = 0; i < cnt; i++) {
				String str = (String) list.get(i);
				strArray[i] = new String(str);
			}
			return strArray;
		} else {
			return null;
		}
	}

	public static boolean isValidName(String name) {
		return name.replaceAll(REGEXP_ANY_SPECIAL_CHARS, "").equals(name); //$NON-NLS-1$		
	}

	/**
	 * added some test code
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		String text = "A&%      `&#           $~!@#$%^&*()_-+={}[\"]:|\\:;\"'<,>.?/ \t\r\nZ"; //$NON-NLS-1$

		System.out.println("[" + text + "] <== text"); //$NON-NLS-1$ //$NON-NLS-2$
		System.out.println("[" + text.replaceAll(REGEXP_ANY_SPECIAL_CHARS, " ") //$NON-NLS-1$ //$NON-NLS-2$
				+ "] <== All"); //$NON-NLS-1$
		System.out.println("[" //$NON-NLS-1$
				+ text.replaceAll(REGEXP_INVALID_FILENAME_CHARS, " ") //$NON-NLS-1$
				+ "] <== File Name"); //$NON-NLS-1$
		System.out.println("[" //$NON-NLS-1$
				+ text.replaceAll(REGEXP_INVALID_PUBLISHED_PATH_CHARS, " ") //$NON-NLS-1$
				+ "] <== path"); //$NON-NLS-1$
		System.out.println("[" //$NON-NLS-1$
				+ text.replaceAll(REGEXP_INVALID_PUBLISHED_PATH_CHARS_LINUX,
						" ") + "] <== path, Linux"); //$NON-NLS-1$ //$NON-NLS-2$

		System.out.println(""); //$NON-NLS-1$
	}

	/**
	 * Converts the platform line-separator (\n or \n\r or \r) to &lt;br/&gt;
	 * 
	 * @param text
	 * @return
	 */
	public static String convertNewlinesToHTML(String text) {
		if (text != null) {
			text = text.replaceAll(LINE_FEED_REGEX, HTML_BREAK + LINE_FEED);
			text = text.replaceAll(ESCAPED_LINE_FEED_REGEX, HTML_BREAK
					+ ESCAPED_LINE_FEED);
		}
		return text;
	}

	public static URI toURI(String pathStr) {
		if (pathStr != null && pathStr.length() > 0) {
			IPath path = Path.fromOSString(pathStr);
			try {
				return path.toFile().toURI();
			} catch (Exception e) {
				CommonPlugin.getDefault().getLogger().logError(e);
			}
		}
		return null;
	}

	public static String escapeChar(String text, char c) {
		int i=text.indexOf(c); 
		if ( i < 0 ) {
			return text;
		}
		
		int start = 0;
		StringBuffer buffer = new StringBuffer();
		while ( i > start ) {
			buffer.append(text.substring(start, i)).append("\\"); //$NON-NLS-1$
			start = i;
			i=text.indexOf(c, start+1); 
		}
		
		buffer.append(text.substring(start));
		
		return buffer.toString();
	}
}