/*
 * Copyright (C) 2010, 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.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;
	}

	@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);
	}

	/**
	 * Get the root note bucket
	 *
	 * @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);
	}
}
