/*
 * Copyright (C) 2012 Google Inc. 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.pgm;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeNoException;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
import org.eclipse.jgit.lib.FileMode;
import org.junit.Before;
import org.junit.Test;

public class ArchiveTest extends CLIRepositoryTestCase {
	private Git git;
	private String emptyTree;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		git = new Git(db);
		git.commit().setMessage("initial commit").call();
		emptyTree = db.resolve("HEAD^{tree}").abbreviate(12).name();
	}

	@Test
	public void testEmptyArchive() throws Exception {
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip " + emptyTree, db).outBytes();
		assertArrayEquals(new String[0], listZipEntries(result));
	}

	@Test
	public void testEmptyTar() throws Exception {
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=tar " + emptyTree, db).outBytes();
		assertArrayEquals(new String[0], listTarEntries(result));
	}

	@Test
	public void testUnrecognizedFormat() throws Exception {
		String[] expect = new String[] {
				"fatal: Unknown archive format 'nonsense'", "" };
		String[] actual = executeUnchecked(
				"git archive --format=nonsense " + emptyTree);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testArchiveWithFiles() throws Exception {
		writeTrashFile("a", "a file with content!");
		writeTrashFile("c", ""); // empty file
		writeTrashFile("unrelated", "another file, just for kicks");
		git.add().addFilepattern("a").call();
		git.add().addFilepattern("c").call();
		git.commit().setMessage("populate toplevel").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip HEAD", db).outBytes();
		assertArrayEquals(new String[] { "a", "c" },
				listZipEntries(result));
	}

	private void commitGreeting() throws Exception {
		writeTrashFile("greeting", "hello, world!");
		git.add().addFilepattern("greeting").call();
		git.commit().setMessage("a commit with a file").call();
	}

	@Test
	public void testDefaultFormatIsTar() throws Exception {
		commitGreeting();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive HEAD", db).outBytes();
		assertArrayEquals(new String[] { "greeting" },
				listTarEntries(result));
	}

	@Test
	public void testFormatOverridesFilename() throws Exception {
		File archive = new File(db.getWorkTree(), "format-overrides-name.tar");
		String path = archive.getAbsolutePath();

		commitGreeting();
		assertArrayEquals(new String[] { "" },
				execute("git archive " +
					"--format=zip " +
					shellQuote("--output=" + path) + " " +
					"HEAD"));
		assertContainsEntryWithMode(path, "", "greeting");
		assertIsZip(archive);
	}

	@Test
	public void testUnrecognizedExtensionMeansTar() throws Exception {
		File archive = new File(db.getWorkTree(), "example.txt");
		String path = archive.getAbsolutePath();

		commitGreeting();
		assertArrayEquals(new String[] { "" },
				execute("git archive " +
					shellQuote("--output=" + path) + " " +
					"HEAD"));
		assertTarContainsEntry(path, "", "greeting");
		assertIsTar(archive);
	}

	@Test
	public void testNoExtensionMeansTar() throws Exception {
		File archive = new File(db.getWorkTree(), "example");
		String path = archive.getAbsolutePath();

		commitGreeting();
		assertArrayEquals(new String[] { "" },
				execute("git archive " +
					shellQuote("--output=" + path) + " " +
					"HEAD"));
		assertIsTar(archive);
	}

	@Test
	public void testExtensionMatchIsAnchored() throws Exception {
		File archive = new File(db.getWorkTree(), "two-extensions.zip.bak");
		String path = archive.getAbsolutePath();

		commitGreeting();
		assertArrayEquals(new String[] { "" },
				execute("git archive " +
					shellQuote("--output=" + path) + " " +
					"HEAD"));
		assertIsTar(archive);
	}

	@Test
	public void testZipExtension() throws Exception {
		File archiveWithDot = new File(db.getWorkTree(), "greeting.zip");
		File archiveNoDot = new File(db.getWorkTree(), "greetingzip");

		commitGreeting();
		execute("git archive " +
			shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " +
			"HEAD");
		execute("git archive " +
			shellQuote("--output=" + archiveNoDot.getAbsolutePath()) + " " +
			"HEAD");
		assertIsZip(archiveWithDot);
		assertIsTar(archiveNoDot);
	}

	@Test
	public void testTarExtension() throws Exception {
		File archive = new File(db.getWorkTree(), "tarball.tar");
		String path = archive.getAbsolutePath();

		commitGreeting();
		assertArrayEquals(new String[] { "" },
				execute("git archive " +
					shellQuote("--output=" + path) + " " +
					"HEAD"));
		assertIsTar(archive);
	}

	@Test
	public void testTgzExtensions() throws Exception {
		commitGreeting();

		for (String ext : Arrays.asList("tar.gz", "tgz")) {
			File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext);
			File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext);

			execute("git archive " +
				shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " +
				"HEAD");
			execute("git archive " +
				shellQuote("--output=" + archiveNoDot.getAbsolutePath()) + " " +
				"HEAD");
			assertIsGzip(archiveWithDot);
			assertIsTar(archiveNoDot);
		}
	}

	@Test
	public void testTbz2Extension() throws Exception {
		commitGreeting();

		for (String ext : Arrays.asList("tar.bz2", "tbz", "tbz2")) {
			File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext);
			File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext);

			execute("git archive " +
				shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " +
				"HEAD");
			execute("git archive " +
				shellQuote("--output=" + archiveNoDot.getAbsolutePath()) + " " +
				"HEAD");
			assertIsBzip2(archiveWithDot);
			assertIsTar(archiveNoDot);
		}
	}

	@Test
	public void testTxzExtension() throws Exception {
		commitGreeting();

		for (String ext : Arrays.asList("tar.xz", "txz")) {
			File archiveWithDot = new File(db.getWorkTree(), "tarball." + ext);
			File archiveNoDot = new File(db.getWorkTree(), "tarball" + ext);

			execute("git archive " +
				shellQuote("--output=" + archiveWithDot.getAbsolutePath()) + " " +
				"HEAD");
			execute("git archive " +
				shellQuote("--output=" + archiveNoDot.getAbsolutePath()) + " " +
				"HEAD");
			assertIsXz(archiveWithDot);
			assertIsTar(archiveNoDot);
		}
	}

	@Test
	public void testArchiveWithSubdir() throws Exception {
		writeTrashFile("a", "a file with content!");
		writeTrashFile("b.c", "before subdir in git sort order");
		writeTrashFile("b0c", "after subdir in git sort order");
		writeTrashFile("c", "");
		git.add().addFilepattern("a").call();
		git.add().addFilepattern("b.c").call();
		git.add().addFilepattern("b0c").call();
		git.add().addFilepattern("c").call();
		git.commit().setMessage("populate toplevel").call();
		writeTrashFile("b/b", "file in subdirectory");
		writeTrashFile("b/a", "another file in subdirectory");
		git.add().addFilepattern("b").call();
		git.commit().setMessage("add subdir").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip master", db).outBytes();
		String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" };
		String[] actual = listZipEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testTarWithSubdir() throws Exception {
		writeTrashFile("a", "a file with content!");
		writeTrashFile("b.c", "before subdir in git sort order");
		writeTrashFile("b0c", "after subdir in git sort order");
		writeTrashFile("c", "");
		git.add().addFilepattern("a").call();
		git.add().addFilepattern("b.c").call();
		git.add().addFilepattern("b0c").call();
		git.add().addFilepattern("c").call();
		git.commit().setMessage("populate toplevel").call();
		writeTrashFile("b/b", "file in subdirectory");
		writeTrashFile("b/a", "another file in subdirectory");
		git.add().addFilepattern("b").call();
		git.commit().setMessage("add subdir").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=tar master", db).outBytes();
		String[] expect = { "a", "b.c", "b0c", "b/", "b/a", "b/b", "c" };
		String[] actual = listTarEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	private void commitBazAndFooSlashBar() throws Exception {
		writeTrashFile("baz", "a file");
		writeTrashFile("foo/bar", "another file");
		git.add().addFilepattern("baz").call();
		git.add().addFilepattern("foo").call();
		git.commit().setMessage("sample commit").call();
	}

	@Test
	public void testArchivePrefixOption() throws Exception {
		commitBazAndFooSlashBar();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=x/ --format=zip master", db).outBytes();
		String[] expect = { "x/", "x/baz", "x/foo/", "x/foo/bar" };
		String[] actual = listZipEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testTarPrefixOption() throws Exception {
		commitBazAndFooSlashBar();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=x/ --format=tar master", db).outBytes();
		String[] expect = { "x/", "x/baz", "x/foo/", "x/foo/bar" };
		String[] actual = listTarEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	private void commitFoo() throws Exception {
		writeTrashFile("foo", "a file");
		git.add().addFilepattern("foo").call();
		git.commit().setMessage("boring commit").call();
	}

	@Test
	public void testPrefixDoesNotNormalizeDoubleSlash() throws Exception {
		commitFoo();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=x// --format=zip master", db).outBytes();
		String[] expect = { "x/", "x//foo" };
		assertArrayEquals(expect, listZipEntries(result));
	}

	@Test
	public void testPrefixDoesNotNormalizeDoubleSlashInTar() throws Exception {
		commitFoo();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=x// --format=tar master", db).outBytes();
		String[] expect = { "x/", "x//foo" };
		assertArrayEquals(expect, listTarEntries(result));
	}

	/**
	 * The prefix passed to "git archive" need not end with '/'.
	 * In practice it is not very common to have a nonempty prefix
	 * that does not name a directory (and hence end with /), but
	 * since git has historically supported other prefixes, we do,
	 * too.
	 *
	 * @throws Exception
	 */
	@Test
	public void testPrefixWithoutTrailingSlash() throws Exception {
		commitBazAndFooSlashBar();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=my- --format=zip master", db).outBytes();
		String[] expect = { "my-baz", "my-foo/", "my-foo/bar" };
		String[] actual = listZipEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testTarPrefixWithoutTrailingSlash() throws Exception {
		commitBazAndFooSlashBar();
		byte[] result = CLIGitCommand.executeRaw(
				"git archive --prefix=my- --format=tar master", db).outBytes();
		String[] expect = { "my-baz", "my-foo/", "my-foo/bar" };
		String[] actual = listTarEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testArchiveIncludesSubmoduleDirectory() throws Exception {
		writeTrashFile("a", "a file with content!");
		writeTrashFile("c", "after submodule");
		git.add().addFilepattern("a").call();
		git.add().addFilepattern("c").call();
		git.commit().setMessage("initial commit").call();
		git.submoduleAdd().setURI("./.").setPath("b").call().close();
		git.commit().setMessage("add submodule").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip master", db).outBytes();
		String[] expect = { ".gitmodules", "a", "b/", "c" };
		String[] actual = listZipEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testTarIncludesSubmoduleDirectory() throws Exception {
		writeTrashFile("a", "a file with content!");
		writeTrashFile("c", "after submodule");
		git.add().addFilepattern("a").call();
		git.add().addFilepattern("c").call();
		git.commit().setMessage("initial commit").call();
		git.submoduleAdd().setURI("./.").setPath("b").call().close();
		git.commit().setMessage("add submodule").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=tar master", db).outBytes();
		String[] expect = { ".gitmodules", "a", "b/", "c" };
		String[] actual = listTarEntries(result);

		Arrays.sort(expect);
		Arrays.sort(actual);
		assertArrayEquals(expect, actual);
	}

	@Test
	public void testArchivePreservesMode() throws Exception {
		writeTrashFile("plain", "a file with content");
		writeTrashFile("executable", "an executable file");
		writeTrashFile("symlink", "plain");
		writeTrashFile("dir/content", "clutter in a subdir");
		git.add().addFilepattern("plain").call();
		git.add().addFilepattern("executable").call();
		git.add().addFilepattern("symlink").call();
		git.add().addFilepattern("dir").call();

		DirCache cache = db.lockDirCache();
		cache.getEntry("executable").setFileMode(FileMode.EXECUTABLE_FILE);
		cache.getEntry("symlink").setFileMode(FileMode.SYMLINK);
		cache.write();
		cache.commit();
		cache.unlock();

		git.commit().setMessage("three files with different modes").call();

		byte[] zipData = CLIGitCommand.executeRaw(
				"git archive --format=zip master", db).outBytes();
		writeRaw("zip-with-modes.zip", zipData);
		assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "plain");
		assertContainsEntryWithMode("zip-with-modes.zip", "-rwx", "executable");
		assertContainsEntryWithMode("zip-with-modes.zip", "l", "symlink");
		assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "dir/");
	}

	@Test
	public void testTarPreservesMode() throws Exception {
		writeTrashFile("plain", "a file with content");
		writeTrashFile("executable", "an executable file");
		writeTrashFile("symlink", "plain");
		writeTrashFile("dir/content", "clutter in a subdir");
		git.add().addFilepattern("plain").call();
		git.add().addFilepattern("executable").call();
		git.add().addFilepattern("symlink").call();
		git.add().addFilepattern("dir").call();

		DirCache cache = db.lockDirCache();
		cache.getEntry("executable").setFileMode(FileMode.EXECUTABLE_FILE);
		cache.getEntry("symlink").setFileMode(FileMode.SYMLINK);
		cache.write();
		cache.commit();
		cache.unlock();

		git.commit().setMessage("three files with different modes").call();

		byte[] archive = CLIGitCommand.executeRaw(
				"git archive --format=tar master", db).outBytes();
		writeRaw("with-modes.tar", archive);
		assertTarContainsEntry("with-modes.tar", "-rw-r--r--", "plain");
		assertTarContainsEntry("with-modes.tar", "-rwxr-xr-x", "executable");
		assertTarContainsEntry("with-modes.tar", "l", "symlink -> plain");
		assertTarContainsEntry("with-modes.tar", "drwxr-xr-x", "dir/");
	}

	@Test
	public void testArchiveWithLongFilename() throws Exception {
		StringBuilder filename = new StringBuilder();
		List<String> l = new ArrayList<>();
		for (int i = 0; i < 20; i++) {
			filename.append("1234567890/");
			l.add(filename.toString());
		}
		filename.append("1234567890");
		l.add(filename.toString());
		writeTrashFile(filename.toString(), "file with long path");
		git.add().addFilepattern("1234567890").call();
		git.commit().setMessage("file with long name").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip HEAD", db).outBytes();
		assertArrayEquals(l.toArray(new String[0]),
				listZipEntries(result));
	}

	@Test
	public void testTarWithLongFilename() throws Exception {
		StringBuilder filename = new StringBuilder();
		List<String> l = new ArrayList<>();
		for (int i = 0; i < 20; i++) {
			filename.append("1234567890/");
			l.add(filename.toString());
		}
		filename.append("1234567890");
		l.add(filename.toString());
		writeTrashFile(filename.toString(), "file with long path");
		git.add().addFilepattern("1234567890").call();
		git.commit().setMessage("file with long name").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=tar HEAD", db).outBytes();
		assertArrayEquals(l.toArray(new String[0]),
				listTarEntries(result));
	}

	@Test
	public void testArchivePreservesContent() throws Exception {
		String payload = "“The quick brown fox jumps over the lazy dog!”";
		writeTrashFile("xyzzy", payload);
		git.add().addFilepattern("xyzzy").call();
		git.commit().setMessage("add file with content").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=zip HEAD", db).outBytes();
		assertArrayEquals(new String[] { payload },
				zipEntryContent(result, "xyzzy"));
	}

	@Test
	public void testTarPreservesContent() throws Exception {
		String payload = "“The quick brown fox jumps over the lazy dog!”";
		writeTrashFile("xyzzy", payload);
		git.add().addFilepattern("xyzzy").call();
		git.commit().setMessage("add file with content").call();

		byte[] result = CLIGitCommand.executeRaw(
				"git archive --format=tar HEAD", db).outBytes();
		assertArrayEquals(new String[] { payload },
				tarEntryContent(result, "xyzzy"));
	}

	private Process spawnAssumingCommandPresent(String... cmdline) {
		File cwd = db.getWorkTree();
		ProcessBuilder procBuilder = new ProcessBuilder(cmdline)
				.directory(cwd)
				.redirectErrorStream(true);
		Process proc = null;
		try {
			proc = procBuilder.start();
		} catch (IOException e) {
			// On machines without `cmdline[0]`, let the test pass.
			assumeNoException(e);
		}

		return proc;
	}

	private BufferedReader readFromProcess(Process proc) throws Exception {
		return new BufferedReader(
				new InputStreamReader(proc.getInputStream(), UTF_8));
	}

	private void grepForEntry(String name, String mode, String... cmdline)
			throws Exception {
		Process proc = spawnAssumingCommandPresent(cmdline);
		proc.getOutputStream().close();
		BufferedReader reader = readFromProcess(proc);
		try {
			String line;
			while ((line = reader.readLine()) != null)
				if (line.startsWith(mode) && line.endsWith(name))
					// found it!
					return;
			fail("expected entry " + name + " with mode " + mode + " but found none");
		} finally {
			proc.getOutputStream().close();
			proc.destroy();
		}
	}

	private void assertMagic(long offset, byte[] magicBytes, File file) throws Exception {
		try (BufferedInputStream in = new BufferedInputStream(
				new FileInputStream(file))) {
			if (offset > 0) {
				long skipped = in.skip(offset);
				assertEquals(offset, skipped);
			}

			byte[] actual = new byte[magicBytes.length];
			in.read(actual);
			assertArrayEquals(magicBytes, actual);
		}
	}

	private void assertMagic(byte[] magicBytes, File file) throws Exception {
		assertMagic(0, magicBytes, file);
	}

	private void assertIsTar(File file) throws Exception {
		assertMagic(257, new byte[] { 'u', 's', 't', 'a', 'r', 0 }, file);
	}

	private void assertIsZip(File file) throws Exception {
		assertMagic(new byte[] { 'P', 'K', 3, 4 }, file);
	}

	private void assertIsGzip(File file) throws Exception {
		assertMagic(new byte[] { 037, (byte) 0213 }, file);
	}

	private void assertIsBzip2(File file) throws Exception {
		assertMagic(new byte[] { 'B', 'Z', 'h' }, file);
	}

	private void assertIsXz(File file) throws Exception {
		assertMagic(new byte[] { (byte) 0xfd, '7', 'z', 'X', 'Z', 0 }, file);
	}

	private void assertContainsEntryWithMode(String zipFilename, String mode, String name)
			throws Exception {
		grepForEntry(name, mode, "zipinfo", zipFilename);
	}

	private void assertTarContainsEntry(String tarfile, String mode, String name)
			throws Exception {
		grepForEntry(name, mode, "tar", "tvf", tarfile);
	}

	private void writeRaw(String filename, byte[] data)
			throws IOException {
		File path = new File(db.getWorkTree(), filename);
		try (OutputStream out = new FileOutputStream(path)) {
			out.write(data);
		}
	}

	private static String[] listZipEntries(byte[] zipData) throws IOException {
		List<String> l = new ArrayList<>();
		try (ZipInputStream in = new ZipInputStream(
				new ByteArrayInputStream(zipData))) {
			ZipEntry e;
			while ((e = in.getNextEntry()) != null)
				l.add(e.getName());
		}
		return l.toArray(new String[0]);
	}

	private static Future<Object> writeAsync(OutputStream stream, byte[] data) {
		ExecutorService executor = Executors.newSingleThreadExecutor();

		return executor.submit(() -> {
			try {
				stream.write(data);
				return null;
			} finally {
				stream.close();
			}
		});
	}

	private String[] listTarEntries(byte[] tarData) throws Exception {
		List<String> l = new ArrayList<>();
		Process proc = spawnAssumingCommandPresent("tar", "tf", "-");
		try (BufferedReader reader = readFromProcess(proc)) {
			OutputStream out = proc.getOutputStream();

			// Dump tarball to tar stdin in background
			Future<?> writing = writeAsync(out, tarData);

			try {
				String line;
				while ((line = reader.readLine()) != null)
					l.add(line);

				return l.toArray(new String[0]);
			} finally {
				writing.get();
				proc.destroy();
			}
		}
	}

	private static String[] zipEntryContent(byte[] zipData, String path)
			throws IOException {
		ZipInputStream in = new ZipInputStream(
				new ByteArrayInputStream(zipData));
		ZipEntry e;
		while ((e = in.getNextEntry()) != null) {
			if (!e.getName().equals(path))
				continue;

			// found!
			List<String> l = new ArrayList<>();
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(in, UTF_8));
			String line;
			while ((line = reader.readLine()) != null)
				l.add(line);
			return l.toArray(new String[0]);
		}

		// not found
		return null;
	}

	private String[] tarEntryContent(byte[] tarData, String path)
			throws Exception {
		List<String> l = new ArrayList<>();
		Process proc = spawnAssumingCommandPresent("tar", "Oxf", "-", path);
		try (BufferedReader reader = readFromProcess(proc)) {
			OutputStream out = proc.getOutputStream();
			Future<?> writing = writeAsync(out, tarData);

			try {
				String line;
				while ((line = reader.readLine()) != null)
					l.add(line);

				return l.toArray(new String[0]);
			} finally {
				writing.get();
				proc.destroy();
			}
		}
	}
}
