/*
 * Copyright (C) 2013, Robin Rosenberg <robin.rosenberg@dewire.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * 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.treewalk.filter;

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

import java.io.IOException;

import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Before;
import org.junit.Test;

public class InterIndexDiffFilterTest extends LocalDiskRepositoryTestCase {

	private Repository db;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		db = createWorkRepository();
	}

	@Test
	public void testEmpty() throws IOException {
		DirCache dc1 = DirCache.newInCore();
		DirCache dc2 = DirCache.newInCore();
		try (TreeWalk tw = new TreeWalk(db)) {
			tw.addTree(new DirCacheIterator(dc1));
			tw.addTree(new DirCacheIterator(dc2));
			assertFalse(tw.next());
		}
	}

	static final class AddEdit extends PathEdit {

		private final ObjectId data;

		private final long length;

		private boolean assumeValid;

		private FileMode type;

		public AddEdit(String entryPath, FileMode type, ObjectId data,
				long length,
				boolean assumeValid) {
			super(entryPath);
			this.type = type;
			this.data = data;
			this.length = length;
			this.assumeValid = assumeValid;
		}

		@Override
		public void apply(DirCacheEntry ent) {
			ent.setFileMode(type);
			ent.setLength(length);
			ent.setObjectId(data);
			ent.setAssumeValid(assumeValid);
		}
	}

	private ObjectId id(String data) {
		byte[] bytes = data.getBytes(UTF_8);
		return db.newObjectInserter().idFor(Constants.OBJ_BLOB, bytes);
	}

	@Test
	public void testOneOnly() throws IOException {
		DirCache dc1 = DirCache.newInCore();
		DirCache dc2 = DirCache.newInCore();
		DirCacheEditor editor = dc1.editor();
		editor.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, false));
		editor.finish();

		try (TreeWalk tw = new TreeWalk(db)) {
			tw.setRecursive(true);
			tw.addTree(new DirCacheIterator(dc1));
			tw.addTree(new DirCacheIterator(dc2));
			tw.setFilter(InterIndexDiffFilter.INSTANCE);
			assertTrue(tw.next());
			assertEquals("a/a", tw.getPathString());
			assertFalse(tw.next());
		}
	}

	@Test
	public void testTwoSame() throws IOException {
		DirCache dc1 = DirCache.newInCore();
		DirCache dc2 = DirCache.newInCore();
		DirCacheEditor ed1 = dc1.editor();
		ed1.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, false));
		ed1.finish();
		DirCacheEditor ed2 = dc2.editor();
		ed2.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, false));
		ed2.finish();

		try (TreeWalk tw = new TreeWalk(db)) {
			tw.setRecursive(true);
			tw.addTree(new DirCacheIterator(dc1));
			tw.addTree(new DirCacheIterator(dc2));
			tw.setFilter(InterIndexDiffFilter.INSTANCE);

			assertFalse(tw.next());
		}
	}

	@Test
	public void testTwoSameDifferByAssumeValid() throws IOException {
		DirCache dc1 = DirCache.newInCore();
		DirCache dc2 = DirCache.newInCore();
		DirCacheEditor ed1 = dc1.editor();
		ed1.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, false));
		ed1.finish();
		DirCacheEditor ed2 = dc2.editor();
		ed2.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, true));
		ed2.finish();

		try (TreeWalk tw = new TreeWalk(db)) {
			tw.setRecursive(true);
			tw.addTree(new DirCacheIterator(dc1));
			tw.addTree(new DirCacheIterator(dc2));
			tw.setFilter(InterIndexDiffFilter.INSTANCE);

			assertTrue(tw.next());
			assertEquals("a/a", tw.getPathString());
			assertFalse(tw.next());
		}
	}

	@Test
	public void testTwoSameSameAssumeValidDifferentContent()
			throws IOException {
		DirCache dc1 = DirCache.newInCore();
		DirCache dc2 = DirCache.newInCore();
		DirCacheEditor ed1 = dc1.editor();
		ed1.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("a"), 1, true));
		ed1.finish();
		DirCacheEditor ed2 = dc2.editor();
		ed2.add(new AddEdit("a/a", FileMode.REGULAR_FILE, id("b"), 1, true));
		ed2.finish();

		try (TreeWalk tw = new TreeWalk(db)) {
			tw.setRecursive(true);
			tw.addTree(new DirCacheIterator(dc1));
			tw.addTree(new DirCacheIterator(dc2));
			tw.setFilter(InterIndexDiffFilter.INSTANCE);

			assertFalse(tw.next());
		}
	}
}
