/*
 * Copyright (C) 2010, Google Inc.
 * 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 java.util.Iterator;

import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
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.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;

/**
 * Index of notes from a note branch.
 *
 * This class is not thread-safe, and relies on an
 * {@link org.eclipse.jgit.lib.ObjectReader} that it borrows/shares with the
 * caller. The reader can be used during any call, and is not released by this
 * class. The caller should arrange for releasing the shared
 * {@code ObjectReader} at the proper times.
 */
public class NoteMap implements Iterable<Note> {
	/**
	 * Construct a new empty note map.
	 *
	 * @return an empty note map.
	 */
	public static NoteMap newEmptyMap() {
		NoteMap r = new NoteMap(null /* no reader */);
		r.root = new LeafBucket(0);
		return r;
	}

	/**
	 * Shorten the note ref name by trimming off the
	 * {@link org.eclipse.jgit.lib.Constants#R_NOTES} prefix if it exists.
	 *
	 * @param noteRefName
	 *            a {@link java.lang.String} object.
	 * @return a more user friendly note name
	 */
	public static String shortenRefName(String noteRefName) {
		if (noteRefName.startsWith(Constants.R_NOTES))
			return noteRefName.substring(Constants.R_NOTES.length());
		return noteRefName;
	}

	/**
	 * Load a collection of notes from a branch.
	 *
	 * @param reader
	 *            reader to scan the note branch with. This reader may be
	 *            retained by the NoteMap for the life of the map in order to
	 *            support lazy loading of entries.
	 * @param commit
	 *            the revision of the note branch to read.
	 * @return the note map read from the commit.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed through the reader.
	 * @throws org.eclipse.jgit.errors.CorruptObjectException
	 *             a tree object is corrupt and cannot be read.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             a tree object wasn't actually a tree.
	 * @throws org.eclipse.jgit.errors.MissingObjectException
	 *             a reference tree object doesn't exist.
	 */
	public static NoteMap read(ObjectReader reader, RevCommit commit)
			throws MissingObjectException, IncorrectObjectTypeException,
			CorruptObjectException, IOException {
		return read(reader, commit.getTree());
	}

	/**
	 * Load a collection of notes from a tree.
	 *
	 * @param reader
	 *            reader to scan the note branch with. This reader may be
	 *            retained by the NoteMap for the life of the map in order to
	 *            support lazy loading of entries.
	 * @param tree
	 *            the note tree to read.
	 * @return the note map read from the tree.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed through the reader.
	 * @throws org.eclipse.jgit.errors.CorruptObjectException
	 *             a tree object is corrupt and cannot be read.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             a tree object wasn't actually a tree.
	 * @throws org.eclipse.jgit.errors.MissingObjectException
	 *             a reference tree object doesn't exist.
	 */
	public static NoteMap read(ObjectReader reader, RevTree tree)
			throws MissingObjectException, IncorrectObjectTypeException,
			CorruptObjectException, IOException {
		return readTree(reader, tree);
	}

	/**
	 * Load a collection of notes from a tree.
	 *
	 * @param reader
	 *            reader to scan the note branch with. This reader may be
	 *            retained by the NoteMap for the life of the map in order to
	 *            support lazy loading of entries.
	 * @param treeId
	 *            the note tree to read.
	 * @return the note map read from the tree.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed through the reader.
	 * @throws org.eclipse.jgit.errors.CorruptObjectException
	 *             a tree object is corrupt and cannot be read.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             a tree object wasn't actually a tree.
	 * @throws org.eclipse.jgit.errors.MissingObjectException
	 *             a reference tree object doesn't exist.
	 */
	public static NoteMap readTree(ObjectReader reader, ObjectId treeId)
			throws MissingObjectException, IncorrectObjectTypeException,
			CorruptObjectException, IOException {
		NoteMap map = new NoteMap(reader);
		map.load(treeId);
		return map;
	}

	/**
	 * Construct a new note map from an existing note bucket.
	 *
	 * @param root
	 *            the root bucket of this note map
	 * @param reader
	 *            reader to scan the note branch with. This reader may be
	 *            retained by the NoteMap for the life of the map in order to
	 *            support lazy loading of entries.
	 * @return the note map built from the note bucket
	 */
	static NoteMap newMap(InMemoryNoteBucket root, ObjectReader reader) {
		NoteMap map = new NoteMap(reader);
		map.root = root;
		return map;
	}

	/** Borrowed reader to access the repository. */
	private final ObjectReader reader;

	/** All of the notes that have been loaded. */
	private InMemoryNoteBucket root;

	private NoteMap(ObjectReader reader) {
		this.reader = reader;
	}

	/** {@inheritDoc} */
	@Override
	public Iterator<Note> iterator() {
		try {
			return root.iterator(new MutableObjectId(), reader);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Lookup a note for a specific ObjectId.
	 *
	 * @param id
	 *            the object to look for.
	 * @return the note's blob ObjectId, or null if no note exists.
	 * @throws java.io.IOException
	 *             a portion of the note space is not accessible.
	 */
	public ObjectId get(AnyObjectId id) throws IOException {
		Note n = root.getNote(id, reader);
		return n == null ? null : n.getData();
	}

	/**
	 * Lookup a note for a specific ObjectId.
	 *
	 * @param id
	 *            the object to look for.
	 * @return the note for the given object id, or null if no note exists.
	 * @throws java.io.IOException
	 *             a portion of the note space is not accessible.
	 */
	public Note getNote(AnyObjectId id) throws IOException {
		return root.getNote(id, reader);
	}

	/**
	 * Determine if a note exists for the specified ObjectId.
	 *
	 * @param id
	 *            the object to look for.
	 * @return true if a note exists; false if there is no note.
	 * @throws java.io.IOException
	 *             a portion of the note space is not accessible.
	 */
	public boolean contains(AnyObjectId id) throws IOException {
		return get(id) != null;
	}

	/**
	 * Open and return the content of an object's note.
	 *
	 * This method assumes the note is fairly small and can be accessed
	 * efficiently. Larger notes should be accessed by streaming:
	 *
	 * <pre>
	 * ObjectId dataId = thisMap.get(id);
	 * if (dataId != null)
	 * 	reader.open(dataId).openStream();
	 * </pre>
	 *
	 * @param id
	 *            object to lookup the note of.
	 * @param sizeLimit
	 *            maximum number of bytes to return. If the note data size is
	 *            larger than this limit, LargeObjectException will be thrown.
	 * @return if a note is defined for {@code id}, the note content. If no note
	 *         is defined, null.
	 * @throws org.eclipse.jgit.errors.LargeObjectException
	 *             the note data is larger than {@code sizeLimit}.
	 * @throws org.eclipse.jgit.errors.MissingObjectException
	 *             the note's blob does not exist in the repository.
	 * @throws java.io.IOException
	 *             the note's blob cannot be read from the repository
	 */
	public byte[] getCachedBytes(AnyObjectId id, int sizeLimit)
			throws LargeObjectException, MissingObjectException, IOException {
		ObjectId dataId = get(id);
		if (dataId != null) {
			return reader.open(dataId).getCachedBytes(sizeLimit);
		}
		return null;
	}

	/**
	 * Attach (or remove) a note on an object.
	 *
	 * If no note exists, a new note is stored. If a note already exists for the
	 * given object, it is replaced (or removed).
	 *
	 * This method only updates the map in memory.
	 *
	 * If the caller wants to attach a UTF-8 encoded string message to an
	 * object, {@link #set(AnyObjectId, String, ObjectInserter)} is a convenient
	 * way to encode and update a note in one step.
	 *
	 * @param noteOn
	 *            the object to attach the note to. This same ObjectId can later
	 *            be used as an argument to {@link #get(AnyObjectId)} or
	 *            {@link #getCachedBytes(AnyObjectId, int)} to read back the
	 *            {@code noteData}.
	 * @param noteData
	 *            data to associate with the note. This must be the ObjectId of
	 *            a blob that already exists in the repository. If null the note
	 *            will be deleted, if present.
	 * @throws java.io.IOException
	 *             a portion of the note space is not accessible.
	 */
	public void set(AnyObjectId noteOn, ObjectId noteData) throws IOException {
		InMemoryNoteBucket newRoot = root.set(noteOn, noteData, reader);
		if (newRoot == null) {
			newRoot = new LeafBucket(0);
			newRoot.nonNotes = root.nonNotes;
		}
		root = newRoot;
	}

	/**
	 * Attach a note to an object.
	 *
	 * If no note exists, a new note is stored. If a note already exists for the
	 * given object, it is replaced (or removed).
	 *
	 * @param noteOn
	 *            the object to attach the note to. This same ObjectId can later
	 *            be used as an argument to {@link #get(AnyObjectId)} or
	 *            {@link #getCachedBytes(AnyObjectId, int)} to read back the
	 *            {@code noteData}.
	 * @param noteData
	 *            text to store in the note. The text will be UTF-8 encoded when
	 *            stored in the repository. If null the note will be deleted, if
	 *            the empty string a note with the empty string will be stored.
	 * @param ins
	 *            inserter to write the encoded {@code noteData} out as a blob.
	 *            The caller must ensure the inserter is flushed before the
	 *            updated note map is made available for reading.
	 * @throws java.io.IOException
	 *             the note data could not be stored in the repository.
	 */
	public void set(AnyObjectId noteOn, String noteData, ObjectInserter ins)
			throws IOException {
		ObjectId dataId;
		if (noteData != null) {
			byte[] dataUTF8 = Constants.encode(noteData);
			dataId = ins.insert(Constants.OBJ_BLOB, dataUTF8);
		} else {
			dataId = null;
		}
		set(noteOn, dataId);
	}

	/**
	 * Remove a note from an object.
	 *
	 * If no note exists, no action is performed.
	 *
	 * This method only updates the map in memory.
	 *
	 * @param noteOn
	 *            the object to remove the note from.
	 * @throws java.io.IOException
	 *             a portion of the note space is not accessible.
	 */
	public void remove(AnyObjectId noteOn) throws IOException {
		set(noteOn, null);
	}

	/**
	 * Write this note map as a tree.
	 *
	 * @param inserter
	 *            inserter to use when writing trees to the object database.
	 *            Caller is responsible for flushing the inserter before trying
	 *            to read the objects, or exposing them through a reference.
	 * @return the top level tree.
	 * @throws java.io.IOException
	 *             a tree could not be written.
	 */
	public ObjectId writeTree(ObjectInserter inserter) throws IOException {
		return root.writeTree(inserter);
	}

	/** @return the root note bucket */
	InMemoryNoteBucket getRoot() {
		return root;
	}

	private void load(ObjectId rootTree) throws MissingObjectException,
			IncorrectObjectTypeException, CorruptObjectException, IOException {
		AbbreviatedObjectId none = AbbreviatedObjectId.fromString(""); //$NON-NLS-1$
		root = NoteParser.parse(none, rootTree, reader);
	}
}
