/*******************************************************************************
 * Copyright (c) 2005, 2017 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
 *
 *******************************************************************************/
package org.eclipse.dltk.core.tests.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.eclipse.dltk.core.DLTKCore;

public class Util {

	/**
	 * Generate a display string from the given String.
	 *
	 * @param inputString
	 *            the given input string
	 *
	 */
	public static String displayString(String inputString) {
		return displayString(inputString, 0);
	}

	/**
	 * Generate a display string from the given String. It converts:
	 * <ul>
	 * <li>\t to \t</li>
	 * <li>\r to \\r</li>
	 * <li>\n to \n</li>
	 * <li>\b to \\b</li>
	 * <li>\f to \\f</li>
	 * <li>\" to \\\"</li>
	 * <li>\' to \\'</li>
	 * <li>\\ to \\\\</li>
	 * <li>All other characters are unchanged.</li>
	 * </ul>
	 * This method doesn't convert \r\n to \n.
	 * <p>
	 * Example of use: <o>
	 * <li>
	 *
	 * <pre>
	 * input string = &quot;abc\ndef\tghi&quot;,
	 * indent = 3
	 * result = &quot;\&quot;\t\t\tabc\\n&quot; +
	 * 			&quot;\t\t\tdef\tghi\&quot;&quot;
	 * </pre>
	 *
	 * </li>
	 * <li>
	 *
	 * <pre>
	 * input string = &quot;abc\ndef\tghi\n&quot;,
	 * indent = 3
	 * result = &quot;\&quot;\t\t\tabc\\n&quot; +
	 * 			&quot;\t\t\tdef\tghi\\n\&quot;&quot;
	 * </pre>
	 *
	 * </li>
	 * <li>
	 *
	 * <pre>
	 * input string = &quot;abc\r\ndef\tghi\r\n&quot;,
	 * indent = 3
	 * result = &quot;\&quot;\t\t\tabc\\r\\n&quot; +
	 * 			&quot;\t\t\tdef\tghi\\r\\n\&quot;&quot;
	 * </pre>
	 *
	 * </li>
	 * </ol>
	 * </p>
	 *
	 * @param inputString
	 *            the given input string
	 * @param indent
	 *            number of tabs are added at the begining of each line.
	 *
	 * @return the displayed string
	 */
	public static String displayString(String inputString, int indent) {
		return displayString(inputString, indent, false);
	}

	public static String displayString(String inputString, int indent,
			boolean shift) {
		if (inputString == null)
			return "null";
		int length = inputString.length();
		StringBuffer buffer = new StringBuffer(length);
		java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(
				inputString, "\n\r", true);
		for (int i = 0; i < indent; i++)
			buffer.append("\t");
		if (shift)
			indent++;
		buffer.append("\"");
		while (tokenizer.hasMoreTokens()) {

			String token = tokenizer.nextToken();
			if (token.equals("\r")) {
				buffer.append("\\r");
				if (tokenizer.hasMoreTokens()) {
					token = tokenizer.nextToken();
					if (token.equals("\n")) {
						buffer.append("\\n");
						if (tokenizer.hasMoreTokens()) {
							buffer.append("\" + \n");
							for (int i = 0; i < indent; i++)
								buffer.append("\t");
							buffer.append("\"");
						}
						continue;
					}
					buffer.append("\" + \n");
					for (int i = 0; i < indent; i++)
						buffer.append("\t");
					buffer.append("\"");
				} else {
					continue;
				}
			} else if (token.equals("\n")) {
				buffer.append("\\n");
				if (tokenizer.hasMoreTokens()) {
					buffer.append("\" + \n");
					for (int i = 0; i < indent; i++)
						buffer.append("\t");
					buffer.append("\"");
				}
				continue;
			}

			StringBuffer tokenBuffer = new StringBuffer();
			for (int i = 0; i < token.length(); i++) {
				char c = token.charAt(i);
				switch (c) {
				case '\r':
					tokenBuffer.append("\\r");
					break;
				case '\n':
					tokenBuffer.append("\\n");
					break;
				case '\b':
					tokenBuffer.append("\\b");
					break;
				case '\t':
					tokenBuffer.append("\t");
					break;
				case '\f':
					tokenBuffer.append("\\f");
					break;
				case '\"':
					tokenBuffer.append("\\\"");
					break;
				case '\'':
					tokenBuffer.append("\\'");
					break;
				case '\\':
					tokenBuffer.append("\\\\");
					break;
				default:
					tokenBuffer.append(c);
				}
			}
			buffer.append(tokenBuffer.toString());
		}
		buffer.append("\"");
		return buffer.toString();
	}

	public static String convertToIndependantLineDelimiter(String source) {
		if (source.indexOf('\n') == -1 && source.indexOf('\r') == -1)
			return source;
		StringBuffer buffer = new StringBuffer();
		for (int i = 0, length = source.length(); i < length; i++) {
			char car = source.charAt(i);
			if (car == '\r') {
				buffer.append('\n');
				if (i < length - 1 && source.charAt(i + 1) == '\n') {
					i++; // skip \n after \r
				}
			} else {
				buffer.append(car);
			}
		}
		return buffer.toString();
	}

	/**
	 * Unzip the contents of the given zip in the given directory (create it if
	 * it doesn't exist)
	 */
	public static void unzip(String zipPath, String destDirPath)
			throws IOException {

		try (InputStream zipIn = new FileInputStream(zipPath)) {
			byte[] buf = new byte[8192];
			File destDir = new File(destDirPath);
			try (ZipInputStream zis = new ZipInputStream(zipIn)) {
				FileOutputStream fos = null;
				try {
					ZipEntry zEntry;
					while ((zEntry = zis.getNextEntry()) != null) {
						// if it is empty directory, create it
						if (zEntry.isDirectory()) {
							new File(destDir, zEntry.getName()).mkdirs();
							continue;
						}
						// if it is a file, extract it
						File outFile = new File(destDir, zEntry.getName());
						// create directory for a file
						outFile.getParentFile().mkdirs();
						// write file
						fos = new FileOutputStream(outFile);
						int n = 0;
						while ((n = zis.read(buf)) >= 0) {
							fos.write(buf, 0, n);
						}
						fos.close();
					}
				} catch (IOException ioe) {
					if (fos != null) {
						try {
							fos.close();
						} catch (IOException ioe2) {
						}
					}
				}
			}
		}
	}

	public static void copyFiles(String from, String to) {
		File file = new File(from);
		File toFolder = new File(to);
		if (!file.exists() || !file.isDirectory()) {
			return;
		}
		File[] files = file.listFiles();
		for (int i = 0; i < files.length; i++) {
			File child = new File(toFolder, files[i].getName());
			if (files[i].isDirectory()) {
				child.mkdir();
				copyFiles(files[i].getAbsolutePath(), child.getAbsolutePath());
			} else if (files[i].isFile()) {
				BufferedInputStream input;
				try {
					input = new BufferedInputStream(
							new FileInputStream(files[i]));
					org.eclipse.dltk.compiler.util.Util.copy(child, input);
					input.close();
				} catch (FileNotFoundException e) {
					if (DLTKCore.DEBUG) {
						e.printStackTrace();
					}
				} catch (IOException e) {
					if (DLTKCore.DEBUG) {
						e.printStackTrace();
					}
				}
			}
			child.setLastModified(files[i].lastModified());
		}
	}
}
