/*
 * (c) Copyright Sysdeo SA 2001, 2002.
 * All Rights Reserved.
 */

package com.sysdeo.eclipse.tomcat;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;


/**
 * Utility class for Files operation
 *
 * Use UTF-8 encoding for text file.
 */
public final class FileUtil {

	/**
	 * Constructor
	 */
	private FileUtil() {
		throw new AssertionError();
	}

	/**
	 * readTextFile
	 * @param f File
	 * @return File Text
	 * @throws IOException IOException
	 */
	public static String readTextFile(final File f) throws IOException {

		StringBuilder buf = new StringBuilder();

		try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"))) {
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				buf.append(inputLine);
				buf.append('\n');
			}
		}

		return buf.toString();
	}

	/**
	 *
	 * @param f File
	 * @param content String
	 * @throws IOException IOException
	 */
	public static void toTextFile(final File f, final String content) throws IOException {
		try (FileOutputStream out = new FileOutputStream(f)) {
			out.write(content.getBytes("UTF-8"));
		}
	}

	/**
	 * copy file
	 * @param inputFilename String
	 * @param outputFilename String
	 * @throws IOException IOException
	 */
	public static void copy(final String inputFilename, final String outputFilename) throws IOException {
		copy(new File(inputFilename), new File(outputFilename));
	}

	/**
	 * Copie un fichier vers un autre fichier ou un r�pertoire vers un autre r�pertoire
	 * @param input File
	 * @param output File
	 * @throws IOException IOException
	 */
	public static void copy(final File input, final File output) throws IOException {
		if (input.isDirectory() && output.isDirectory()) {
			copyDir(input, output);
		} else {
			copyFile(input, output);
		}
	}

	/**
	 * Copie un fichier vers un autre
	 * @param inputFile File
	 * @param outputFile File
	 * @throws IOException IOException
	 */
	public static void copyFile(final File inputFile, final File outputFile) throws IOException {
		try (BufferedInputStream fr = new BufferedInputStream(new FileInputStream(inputFile))) {
			try (BufferedOutputStream fw = new BufferedOutputStream(new FileOutputStream(outputFile))) {
				byte[] buf = new byte[8192];
				int n;
				while ((n = fr.read(buf)) >= 0) {
					fw.write(buf, 0, n);
				}
			}
		}
    }

	/**
	 * Copie un r�pertoire dans un autre
	 * @param inputDir File
	 * @param outputDir File
	 * @return result
	 * @throws IOException IOException
	 */
	public static boolean copyDir(final File inputDir, final File outputDir) throws IOException {
		boolean ret = true;
		File[] files = inputDir.listFiles();
		if (files != null) {
			for (final File file : files) {
				File destFile = new File(outputDir.getAbsolutePath() + File.separator + file.getName());
				if (!destFile.exists()) {
					if (file.isDirectory()) {
						if (!destFile.mkdir()) {
							ret = false;
							break;
						}
					}
				}
				copy(file, destFile);
			}
		}
		return ret;
	}


	/**
	 * return true if the directory contains files with the extension
	 * @param dir File
	 * @param extension String
	 * @param recursive boolean
	 * @return boolean
	 */
	public static boolean dirContainsFiles(final File dir, final String extension, final boolean recursive) {
		File[] files = dir.listFiles();
		if (files != null) {
			for (final File file : files) {
				if (file.isFile() && file.getName().endsWith(extension)) {
					return true;
				}
				if (recursive && file.isDirectory()) {
					return dirContainsFiles(file, extension, recursive);
				}
			}
		}
		return false;
	}

	/**
	 * readPropertyInXMLFile
	 * @param file File
	 * @param property String
	 * @return String
	 * @throws IOException IOException
	 */
	public static String readPropertyInXMLFile(final File file, final String property) throws IOException {
		String content = readTextFile(file);
		int startTagIdx = content.indexOf("<" + property + ">");
		int endTagIdx = content.indexOf("</" + property + ">");
		if (startTagIdx == -1) {
			throw new IOException("Property " + property + " not found in file " + file);
		}
		return content.substring(startTagIdx + property.length() + 2, endTagIdx);
	}

	/**
	 * Recursive delete of a directory.<br>
	 * The directory itself will be deleted
	 * @param dir File
	 * @return result
	 * @throws IOException IOException
	 */
	public static boolean removeDir(final File dir) throws IOException {
		boolean ret = true;
		File[] files = dir.listFiles();
		if (files != null) {
			for (int i = 0; ret && i < files.length; i++) {
				if (files[i].isDirectory()) {
					ret = removeDir(files[i]);
				} else {
					ret = files[i].delete();
				}
			}
			if (!ret) {
				ret = dir.delete();
			}
		}
		return ret;
	}
}
