/*
 * Copyright (C) 2008-2009, Google Inc.
 * Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
 * Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.junit;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;

import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Assert;
import org.junit.Test;

/**
 * Abstract test util class
 */
public abstract class JGitTestUtil {
	/** Constant <code>CLASSPATH_TO_RESOURCES="org/eclipse/jgit/test/resources/"</code> */
	public static final String CLASSPATH_TO_RESOURCES = "org/eclipse/jgit/test/resources/";

	private JGitTestUtil() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Get name of current test by inspecting stack trace
	 *
	 * @return the name
	 */
	public static String getName() {
		GatherStackTrace stack;
		try {
			throw new GatherStackTrace();
		} catch (GatherStackTrace wanted) {
			stack = wanted;
		}

		try {
			for (StackTraceElement stackTrace : stack.getStackTrace()) {
				String className = stackTrace.getClassName();
				String methodName = stackTrace.getMethodName();
				Method method;
				try {
					method = Class.forName(className) //
							.getMethod(methodName, (Class[]) null);
				} catch (NoSuchMethodException e) {
					// could be private, i.e. not a test method
					// could have arguments, not handled
					continue;
				}

				Test annotation = method.getAnnotation(Test.class);
				if (annotation != null)
					return methodName;
			}
		} catch (ClassNotFoundException shouldNeverOccur) {
			// Fall through and crash.
		}

		throw new AssertionError("Cannot determine name of current test");
	}

	@SuppressWarnings("serial")
	private static class GatherStackTrace extends Exception {
		// Thrown above to collect the stack frame.
	}

	/**
	 * Assert byte arrays are equal
	 *
	 * @param exp
	 *            expected value
	 * @param act
	 *            actual value
	 */
	public static void assertEquals(byte[] exp, byte[] act) {
		Assert.assertEquals(s(exp), s(act));
	}

	private static String s(byte[] raw) {
		return RawParseUtils.decode(raw);
	}

	/**
	 * Get test resource file.
	 *
	 * @param fileName
	 *            file name
	 * @return the test resource file
	 */
	public static File getTestResourceFile(String fileName) {
		if (fileName == null || fileName.length() <= 0) {
			return null;
		}
		final URL url = cl().getResource(CLASSPATH_TO_RESOURCES + fileName);
		if (url == null) {
			// If URL is null then try to load it as it was being
			// loaded previously
			return new File("tst", fileName);
		}
		if ("jar".equals(url.getProtocol())) {
			try {
				File tmp = File.createTempFile("tmp_", "_" + fileName);
				copyTestResource(fileName, tmp);
				return tmp;
			} catch (IOException err) {
				throw new RuntimeException("Cannot create temporary file", err);
			}
		}
		try {
			return new File(url.toURI());
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException(e.getMessage() + " " + url);
		} catch (URISyntaxException e) {
			return new File(url.getPath());
		}
	}

	/**
	 * Copy test resource.
	 *
	 * @param name
	 *            resource name
	 * @param dest
	 *            destination file
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public static void copyTestResource(String name, File dest)
			throws IOException {
		URL url = cl().getResource(CLASSPATH_TO_RESOURCES + name);
		if (url == null)
			throw new FileNotFoundException(name);
		try (InputStream in = url.openStream();
				FileOutputStream out = new FileOutputStream(dest)) {
			byte[] buf = new byte[4096];
			for (int n; (n = in.read(buf)) > 0;)
				out.write(buf, 0, n);
		}
	}

	private static ClassLoader cl() {
		return JGitTestUtil.class.getClassLoader();
	}

	/**
	 * Write a trash file.
	 *
	 * @param db
	 *            the repository
	 * @param name
	 *            file name
	 * @param data
	 *            file content
	 * @return the trash file
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public static File writeTrashFile(final Repository db,
			final String name, final String data) throws IOException {
		File path = new File(db.getWorkTree(), name);
		write(path, data);
		return path;
	}

	/**
	 * Write a trash file.
	 *
	 * @param db
	 *            the repository
	 * @param subdir
	 *            under working tree
	 * @param name
	 *            file name
	 * @param data
	 *            file content
	 * @return the trash file
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public static File writeTrashFile(final Repository db,
			final String subdir,
			final String name, final String data) throws IOException {
		File path = new File(db.getWorkTree() + "/" + subdir, name);
		write(path, data);
		return path;
	}

	/**
	 * Write a string as a UTF-8 file.
	 *
	 * @param f
	 *            file to write the string to. Caller is responsible for making
	 *            sure it is in the trash directory or will otherwise be cleaned
	 *            up at the end of the test. If the parent directory does not
	 *            exist, the missing parent directories are automatically
	 *            created.
	 * @param body
	 *            content to write to the file.
	 * @throws IOException
	 *             the file could not be written.
	 */
	public static void write(File f, String body)
			throws IOException {
		FileUtils.mkdirs(f.getParentFile(), true);
		try (Writer w = new OutputStreamWriter(new FileOutputStream(f),
				UTF_8)) {
			w.write(body);
		}
	}

	/**
	 * Fully read a UTF-8 file and return as a string.
	 *
	 * @param file
	 *            file to read the content of.
	 * @return UTF-8 decoded content of the file, empty string if the file
	 *         exists but has no content.
	 * @throws IOException
	 *             the file does not exist, or could not be read.
	 */
	public static String read(File file) throws IOException {
		final byte[] body = IO.readFully(file);
		return new String(body, 0, body.length, UTF_8);
	}

	/**
	 * Read a file's content
	 *
	 * @param db
	 *            the repository
	 * @param name
	 *            file name
	 * @return the content of the file
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public static String read(Repository db, String name)
			throws IOException {
		File file = new File(db.getWorkTree(), name);
		return read(file);
	}

	/**
	 * Check if file exists
	 *
	 * @param db
	 *            the repository
	 * @param name
	 *            name of the file
	 * @return {@code true} if the file exists
	 */
	public static boolean check(Repository db, String name) {
		File file = new File(db.getWorkTree(), name);
		return file.exists();
	}

	/**
	 * Delete a trash file.
	 *
	 * @param db
	 *            the repository
	 * @param name
	 *            file name
	 * @throws IOException
	 *             if an IO error occurred
	 */
	public static void deleteTrashFile(final Repository db,
			final String name) throws IOException {
		File path = new File(db.getWorkTree(), name);
		FileUtils.delete(path);
	}

	/**
	 * Write a symbolic link
	 *
	 * @param db
	 *            the repository
	 * @param link
	 *            the path of the symbolic link to create
	 * @param target
	 *            the target of the symbolic link
	 * @return the path to the symbolic link
	 * @throws Exception
	 *             if an error occurred
	 * @since 4.2
	 */
	public static Path writeLink(Repository db, String link,
			String target) throws Exception {
		return FileUtils.createSymLink(new File(db.getWorkTree(), link),
				target);
	}

	/**
	 * Concatenate byte arrays.
	 *
	 * @param b
	 *            byte arrays to combine together.
	 * @return a single byte array that contains all bytes copied from input
	 *         byte arrays.
	 * @since 4.9
	 */
	public static byte[] concat(byte[]... b) {
		int n = 0;
		for (byte[] a : b) {
			n += a.length;
		}

		byte[] data = new byte[n];
		n = 0;
		for (byte[] a : b) {
			System.arraycopy(a, 0, data, n, a.length);
			n += a.length;
		}
		return data;
	}
}
