/*
 * Copyright (C) 2012, Roberto Tyley <roberto.tyley@gmail.com>
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.internal.storage.file;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class ObjectDirectoryTest extends RepositoryTestCase {

	@Rule
	public ExpectedException expectedEx = ExpectedException.none();

	@Test
	public void testConcurrentInsertionOfBlobsToTheSameNewFanOutDirectory()
			throws Exception {
		ExecutorService e = Executors.newCachedThreadPool();
		for (int i=0; i < 100; ++i) {
			ObjectDirectory dir = createBareRepository().getObjectDatabase();
			for (Future f : e.invokeAll(blobInsertersForTheSameFanOutDir(dir))) {
				f.get();
			}
		}
	}

	/**
	 * Test packfile scanning while a gc is done from the outside (different
	 * process or different Repository instance). This situation occurs e.g. if
	 * a gerrit server is serving fetch requests while native git is doing a
	 * garbage collection. The test shows that when core.trustfolderstat==true
	 * jgit may miss to detect that a new packfile was created. This situation
	 * is persistent until a new full rescan of the pack directory is triggered.
	 *
	 * The test works with two Repository instances working on the same disk
	 * location. One (db) for all write operations (creating commits, doing gc)
	 * and another one (receivingDB) which just reads and which in the end shows
	 * the bug
	 *
	 * @throws Exception
	 */
	@Test
	public void testScanningForPackfiles() throws Exception {
		ObjectId unknownID = ObjectId
				.fromString("c0ffee09d0b63d694bf49bc1e6847473f42d4a8c");
		GC gc = new GC(db);
		gc.setExpireAgeMillis(0);
		gc.setPackExpireAgeMillis(0);

		// the default repo db is used to create the objects. The receivingDB
		// repo is used to trigger gc's
		try (FileRepository receivingDB = new FileRepository(
				db.getDirectory())) {
			// set trustfolderstat to true. If set to false the test always
			// succeeds.
			FileBasedConfig cfg = receivingDB.getConfig();
			cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
					ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
			cfg.save();

			// setup a repo which has at least one pack file and trigger
			// scanning of the packs directory
			ObjectId id = commitFile("file.txt", "test", "master").getId();
			gc.gc();
			assertFalse(receivingDB.getObjectDatabase().has(unknownID));
			assertTrue(receivingDB.getObjectDatabase().hasPackedObject(id));

			// preparations
			File packsFolder = receivingDB.getObjectDatabase()
					.getPackDirectory();
			// prepare creation of a temporary file in the pack folder. This
			// simulates that a native git gc is happening starting to write
			// temporary files but has not yet finished
			File tmpFile = new File(packsFolder, "1.tmp");
			RevCommit id2 = commitFile("file.txt", "test2", "master");
			// wait until filesystem timer ticks. This raises probability that
			// the next statements are executed in the same tick as the
			// filesystem timer
			fsTick(null);

			// create a Temp file in the packs folder and trigger a rescan of
			// the packs folder. This lets receivingDB think it has scanned the
			// packs folder at the current fs timestamp t1. The following gc
			// will create new files which have the same timestamp t1 but this
			// will not update the mtime of the packs folder. Because of that
			// JGit will not rescan the packs folder later on and fails to see
			// the pack file created during gc.
			assertTrue(tmpFile.createNewFile());
			assertFalse(receivingDB.getObjectDatabase().has(unknownID));

			// trigger a gc. This will create packfiles which have likely the
			// same mtime than the packfolder
			gc.gc();

			// To deal with racy-git situations JGit's Filesnapshot class will
			// report a file/folder potentially dirty if
			// cachedLastReadTime-cachedLastModificationTime < filesystem
			// timestamp resolution. This causes JGit to always rescan a file
			// after modification. But: this was true only if the difference
			// between current system time and cachedLastModification time was
			// less than 2500ms. If the modification is more than 2500ms ago we
			// may have reported a file/folder to be clean although it has not
			// been rescanned. A bug. To show the bug we sleep for more than
			// 2500ms
			Thread.sleep(2600);

			File[] ret = packsFolder.listFiles(
					(File dir, String name) -> name.endsWith(".pack"));
			assertTrue(ret != null && ret.length == 1);
			FS fs = db.getFS();
			Assume.assumeTrue(fs.lastModifiedInstant(tmpFile)
					.equals(fs.lastModifiedInstant(ret[0])));

			// all objects are in a new packfile but we will not detect it
			assertFalse(receivingDB.getObjectDatabase().has(unknownID));
			assertTrue(receivingDB.getObjectDatabase().has(id2));
		}
	}

	@Test
	public void testShallowFile()
			throws Exception {
		FileRepository repository = createBareRepository();
		ObjectDirectory dir = repository.getObjectDatabase();

		String commit = "d3148f9410b071edd4a4c85d2a43d1fa2574b0d2";
		try (PrintWriter writer = new PrintWriter(
				new File(repository.getDirectory(), Constants.SHALLOW),
				UTF_8.name())) {
			writer.println(commit);
		}
		Set<ObjectId> shallowCommits = dir.getShallowCommits();
		assertTrue(shallowCommits.remove(ObjectId.fromString(commit)));
		assertTrue(shallowCommits.isEmpty());
	}

	@Test
	public void testShallowFileCorrupt()
			throws Exception {
		FileRepository repository = createBareRepository();
		ObjectDirectory dir = repository.getObjectDatabase();

		String commit = "X3148f9410b071edd4a4c85d2a43d1fa2574b0d2";
		try (PrintWriter writer = new PrintWriter(
				new File(repository.getDirectory(), Constants.SHALLOW),
				UTF_8.name())) {
			writer.println(commit);
		}

		expectedEx.expect(IOException.class);
		expectedEx.expectMessage(MessageFormat
				.format(JGitText.get().badShallowLine, commit));
		dir.getShallowCommits();
	}

	private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir(
			final ObjectDirectory dir) {
		Callable<ObjectId> callable = () -> dir.newInserter()
				.insert(Constants.OBJ_BLOB, new byte[0]);
		return Collections.nCopies(4, callable);
	}

}
