/*
 * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.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.notes;

import java.io.IOException;

import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.Merger;
import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;

/**
 * Three-way note tree merge.
 * <p>
 * Direct implementation of NoteMap merger without using {@link TreeWalk} and
 * {@link AbstractTreeIterator}
 */
public class NoteMapMerger {
	private static final FanoutBucket EMPTY_FANOUT = new FanoutBucket(0);

	private static final LeafBucket EMPTY_LEAF = new LeafBucket(0);

	private final Repository db;

	private final NoteMerger noteMerger;

	private final MergeStrategy nonNotesMergeStrategy;

	private final ObjectReader reader;

	private final ObjectInserter inserter;

	private final MutableObjectId objectIdPrefix;

	/**
	 * Constructs a NoteMapMerger with custom {@link NoteMerger} and custom
	 * {@link MergeStrategy}.
	 *
	 * @param db
	 *            Git repository
	 * @param noteMerger
	 *            note merger for merging conflicting changes on a note
	 * @param nonNotesMergeStrategy
	 *            merge strategy for merging non-note entries
	 */
	public NoteMapMerger(Repository db, NoteMerger noteMerger,
			MergeStrategy nonNotesMergeStrategy) {
		this.db = db;
		this.reader = db.newObjectReader();
		this.inserter = db.newObjectInserter();
		this.noteMerger = noteMerger;
		this.nonNotesMergeStrategy = nonNotesMergeStrategy;
		this.objectIdPrefix = new MutableObjectId();
	}

	/**
	 * Constructs a NoteMapMerger with {@link DefaultNoteMerger} as the merger
	 * for notes and the {@link MergeStrategy#RESOLVE} as the strategy for
	 * resolving conflicts on non-notes
	 *
	 * @param db
	 *            Git repository
	 */
	public NoteMapMerger(Repository db) {
		this(db, new DefaultNoteMerger(), MergeStrategy.RESOLVE);
	}

	/**
	 * Performs the merge.
	 *
	 * @param base
	 *            base version of the note tree
	 * @param ours
	 *            ours version of the note tree
	 * @param theirs
	 *            theirs version of the note tree
	 * @return merge result as a new NoteMap
	 * @throws IOException
	 */
	public NoteMap merge(NoteMap base, NoteMap ours, NoteMap theirs)
			throws IOException {
		try {
			InMemoryNoteBucket mergedBucket = merge(0, base.getRoot(),
					ours.getRoot(), theirs.getRoot());
			inserter.flush();
			return NoteMap.newMap(mergedBucket, reader);
		} finally {
			reader.close();
			inserter.close();
		}
	}

	/**
	 * This method is called only when it is known that there is some difference
	 * between base, ours and theirs.
	 *
	 * @param treeDepth
	 * @param base
	 * @param ours
	 * @param theirs
	 * @return merge result as an InMemoryBucket
	 * @throws IOException
	 */
	private InMemoryNoteBucket merge(int treeDepth, InMemoryNoteBucket base,
			InMemoryNoteBucket ours, InMemoryNoteBucket theirs)
			throws IOException {
		InMemoryNoteBucket result;

		if (base instanceof FanoutBucket || ours instanceof FanoutBucket
				|| theirs instanceof FanoutBucket) {
			result = mergeFanoutBucket(treeDepth, asFanout(base),
					asFanout(ours), asFanout(theirs));

		} else {
			result = mergeLeafBucket(treeDepth, (LeafBucket) base,
					(LeafBucket) ours, (LeafBucket) theirs);
		}

		result.nonNotes = mergeNonNotes(nonNotes(base), nonNotes(ours),
				nonNotes(theirs));
		return result;
	}

	private FanoutBucket asFanout(InMemoryNoteBucket bucket) {
		if (bucket == null)
			return EMPTY_FANOUT;
		if (bucket instanceof FanoutBucket)
			return (FanoutBucket) bucket;
		return ((LeafBucket) bucket).split();
	}

	private static NonNoteEntry nonNotes(InMemoryNoteBucket b) {
		return b == null ? null : b.nonNotes;
	}

	private InMemoryNoteBucket mergeFanoutBucket(int treeDepth,
			FanoutBucket base,
			FanoutBucket ours, FanoutBucket theirs) throws IOException {
		FanoutBucket result = new FanoutBucket(treeDepth * 2);
		// walking through entries of base, ours, theirs
		for (int i = 0; i < 256; i++) {
			NoteBucket b = base.getBucket(i);
			NoteBucket o = ours.getBucket(i);
			NoteBucket t = theirs.getBucket(i);

			if (equals(o, t))
				addIfNotNull(result, i, o);

			else if (equals(b, o))
				addIfNotNull(result, i, t);

			else if (equals(b, t))
				addIfNotNull(result, i, o);

			else {
				objectIdPrefix.setByte(treeDepth, i);
				InMemoryNoteBucket mergedBucket = merge(treeDepth + 1,
						FanoutBucket.loadIfLazy(b, objectIdPrefix, reader),
						FanoutBucket.loadIfLazy(o, objectIdPrefix, reader),
						FanoutBucket.loadIfLazy(t, objectIdPrefix, reader));
				result.setBucket(i, mergedBucket);
			}
		}
		return result.contractIfTooSmall(objectIdPrefix, reader);
	}

	private static boolean equals(NoteBucket a, NoteBucket b) {
		if (a == null && b == null)
			return true;
		return a != null && b != null && a.getTreeId().equals(b.getTreeId());
	}

	private void addIfNotNull(FanoutBucket b, int cell, NoteBucket child)
			throws IOException {
		if (child == null)
			return;
		if (child instanceof InMemoryNoteBucket)
			b.setBucket(cell, ((InMemoryNoteBucket) child).writeTree(inserter));
		else
			b.setBucket(cell, child.getTreeId());
	}

	private InMemoryNoteBucket mergeLeafBucket(int treeDepth, LeafBucket bb,
			LeafBucket ob, LeafBucket tb) throws MissingObjectException,
			IOException {
		bb = notNullOrEmpty(bb);
		ob = notNullOrEmpty(ob);
		tb = notNullOrEmpty(tb);

		InMemoryNoteBucket result = new LeafBucket(treeDepth * 2);
		int bi = 0, oi = 0, ti = 0;
		while (bi < bb.size() || oi < ob.size() || ti < tb.size()) {
			Note b = get(bb, bi), o = get(ob, oi), t = get(tb, ti);
			Note min = min(b, o, t);

			b = sameNoteOrNull(min, b);
			o = sameNoteOrNull(min, o);
			t = sameNoteOrNull(min, t);

			if (sameContent(o, t))
				result = addIfNotNull(result, o);

			else if (sameContent(b, o))
				result = addIfNotNull(result, t);

			else if (sameContent(b, t))
				result = addIfNotNull(result, o);

			else
				result = addIfNotNull(result,
						noteMerger.merge(b, o, t, reader, inserter));

			if (b != null)
				bi++;
			if (o != null)
				oi++;
			if (t != null)
				ti++;
		}
		return result;
	}

	private static LeafBucket notNullOrEmpty(LeafBucket b) {
		return b != null ? b : EMPTY_LEAF;
	}

	private static Note get(LeafBucket b, int i) {
		return i < b.size() ? b.get(i) : null;
	}

	private static Note min(Note b, Note o, Note t) {
		Note min = b;
		if (min == null || (o != null && o.compareTo(min) < 0))
			min = o;
		if (min == null || (t != null && t.compareTo(min) < 0))
			min = t;
		return min;
	}

	private static Note sameNoteOrNull(Note min, Note other) {
		return sameNote(min, other) ? other : null;
	}

	private static boolean sameNote(Note a, Note b) {
		if (a == null && b == null)
			return true;
		return a != null && b != null && AnyObjectId.equals(a, b);
	}

	private static boolean sameContent(Note a, Note b) {
		if (a == null && b == null)
			return true;
		return a != null && b != null
				&& AnyObjectId.equals(a.getData(), b.getData());
	}

	private static InMemoryNoteBucket addIfNotNull(InMemoryNoteBucket result,
			Note note) {
		if (note != null)
			return result.append(note);
		else
			return result;
	}

	private NonNoteEntry mergeNonNotes(NonNoteEntry baseList,
			NonNoteEntry oursList, NonNoteEntry theirsList) throws IOException {
		if (baseList == null && oursList == null && theirsList == null)
			return null;

		ObjectId baseId = write(baseList);
		ObjectId oursId = write(oursList);
		ObjectId theirsId = write(theirsList);
		inserter.flush();

		Merger m = nonNotesMergeStrategy.newMerger(db, true);
		if (m instanceof ThreeWayMerger)
			((ThreeWayMerger) m).setBase(baseId);
		if (!m.merge(oursId, theirsId))
			throw new NotesMergeConflictException(baseList, oursList,
					theirsList);
		ObjectId resultTreeId = m.getResultTreeId();
		AbbreviatedObjectId none = AbbreviatedObjectId.fromString(""); //$NON-NLS-1$
		return NoteParser.parse(none, resultTreeId, reader).nonNotes;
	}

	private ObjectId write(NonNoteEntry list)
			throws IOException {
		LeafBucket b = new LeafBucket(0);
		b.nonNotes = list;
		return b.writeTree(inserter);
	}
}
