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

import java.io.IOException;

import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;

/**
 * Collects line annotations for inspection by applications.
 * <p>
 * A result is usually updated incrementally as the BlameGenerator digs back
 * further through history. Applications that want to lay annotations down text
 * to the original source file in a viewer may find the BlameResult structure an
 * easy way to acquire the information, at the expense of keeping tables in
 * memory tracking every line of the result file.
 * <p>
 * This class is not thread-safe.
 * <p>
 * During blame processing there are two files involved:
 * <ul>
 * <li>result - The file whose lines are being examined. This is the revision
 * the user is trying to view blame/annotation information alongside of.</li>
 * <li>source - The file that was blamed with supplying one or more lines of
 * data into result. The source may be a different file path (due to copy or
 * rename). Source line numbers may differ from result line numbers due to lines
 * being added/removed in intermediate revisions.</li>
 * </ul>
 */
public class BlameResult {
	/**
	 * Construct a new BlameResult for a generator.
	 *
	 * @param gen
	 *            the generator the result will consume records from.
	 * @return the new result object. null if the generator cannot find the path
	 *         it starts from.
	 * @throws java.io.IOException
	 *             the repository cannot be read.
	 */
	public static BlameResult create(BlameGenerator gen) throws IOException {
		String path = gen.getResultPath();
		RawText contents = gen.getResultContents();
		if (contents == null) {
			gen.close();
			return null;
		}
		return new BlameResult(gen, path, contents);
	}

	private final String resultPath;

	private final RevCommit[] sourceCommits;

	private final PersonIdent[] sourceAuthors;

	private final PersonIdent[] sourceCommitters;

	private final String[] sourcePaths;

	/** Warning: these are actually 1-based. */
	private final int[] sourceLines;

	private RawText resultContents;

	private BlameGenerator generator;

	private int lastLength;

	BlameResult(BlameGenerator bg, String path, RawText text) {
		generator = bg;
		resultPath = path;
		resultContents = text;

		int cnt = text.size();
		sourceCommits = new RevCommit[cnt];
		sourceAuthors = new PersonIdent[cnt];
		sourceCommitters = new PersonIdent[cnt];
		sourceLines = new int[cnt];
		sourcePaths = new String[cnt];
	}

	/**
	 * Get result path
	 *
	 * @return path of the file this result annotates
	 */
	public String getResultPath() {
		return resultPath;
	}

	/**
	 * Get result contents
	 *
	 * @return contents of the result file, available for display
	 */
	public RawText getResultContents() {
		return resultContents;
	}

	/**
	 * Throw away the {@link #getResultContents()}.
	 */
	public void discardResultContents() {
		resultContents = null;
	}

	/**
	 * Check if the given result line has been annotated yet.
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return true if the data has been annotated, false otherwise.
	 */
	public boolean hasSourceData(int idx) {
		return sourceLines[idx] != 0;
	}

	/**
	 * Check if the given result line has been annotated yet.
	 *
	 * @param start
	 *            first index to examine.
	 * @param end
	 *            last index to examine.
	 * @return true if the data has been annotated, false otherwise.
	 */
	public boolean hasSourceData(int start, int end) {
		for (; start < end; start++)
			if (sourceLines[start] == 0)
				return false;
		return true;
	}

	/**
	 * Get the commit that provided the specified line of the result.
	 * <p>
	 * The source commit may be null if the line was blamed to an uncommitted
	 * revision, such as the working tree copy, or during a reverse blame if the
	 * line survives to the end revision (e.g. the branch tip).
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return commit that provided line {@code idx}. May be null.
	 */
	public RevCommit getSourceCommit(int idx) {
		return sourceCommits[idx];
	}

	/**
	 * Get the author that provided the specified line of the result.
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return author that provided line {@code idx}. May be null.
	 */
	public PersonIdent getSourceAuthor(int idx) {
		return sourceAuthors[idx];
	}

	/**
	 * Get the committer that provided the specified line of the result.
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return committer that provided line {@code idx}. May be null.
	 */
	public PersonIdent getSourceCommitter(int idx) {
		return sourceCommitters[idx];
	}

	/**
	 * Get the file path that provided the specified line of the result.
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return source file path that provided line {@code idx}.
	 */
	public String getSourcePath(int idx) {
		return sourcePaths[idx];
	}

	/**
	 * Get the corresponding line number in the source file.
	 *
	 * @param idx
	 *            line to read data of, 0 based.
	 * @return matching line number in the source file.
	 */
	public int getSourceLine(int idx) {
		return sourceLines[idx] - 1;
	}

	/**
	 * Compute all pending information.
	 *
	 * @throws java.io.IOException
	 *             the repository cannot be read.
	 */
	public void computeAll() throws IOException {
		BlameGenerator gen = generator;
		if (gen == null)
			return;

		try {
			while (gen.next())
				loadFrom(gen);
		} finally {
			gen.close();
			generator = null;
		}
	}

	/**
	 * Compute the next available segment and return the first index.
	 * <p>
	 * Computes one segment and returns to the caller the first index that is
	 * available. After return the caller can also inspect {@link #lastLength()}
	 * to determine how many lines of the result were computed.
	 *
	 * @return index that is now available. -1 if no more are available.
	 * @throws java.io.IOException
	 *             the repository cannot be read.
	 */
	public int computeNext() throws IOException {
		BlameGenerator gen = generator;
		if (gen == null) {
			return -1;
		}

		if (gen.next()) {
			loadFrom(gen);
			lastLength = gen.getRegionLength();
			return gen.getResultStart();
		}
		gen.close();
		generator = null;
		return -1;
	}

	/**
	 * Get last length
	 *
	 * @return length of the last segment found by {@link #computeNext()}
	 */
	public int lastLength() {
		return lastLength;
	}

	/**
	 * Compute until the entire range has been populated.
	 *
	 * @param start
	 *            first index to examine (inclusive).
	 * @param end
	 *            end index (exclusive).
	 * @throws java.io.IOException
	 *             the repository cannot be read.
	 */
	public void computeRange(int start, int end) throws IOException {
		BlameGenerator gen = generator;
		if (gen == null)
			return;
		if (start == 0 && end == resultContents.size()) {
			computeAll();
			return;
		}

		while (start < end) {
			if (hasSourceData(start, end))
				return;

			if (!gen.next()) {
				gen.close();
				generator = null;
				return;
			}

			loadFrom(gen);

			// If the result contains either end of our current range bounds,
			// update the bounds to avoid scanning that section during the
			// next loop iteration.

			int resLine = gen.getResultStart();
			int resEnd = gen.getResultEnd();

			if (resLine <= start && start < resEnd)
				start = resEnd;

			if (resLine <= end && end < resEnd)
				end = resLine;
		}
	}

	/** {@inheritDoc} */
	@Override
	public String toString() {
		StringBuilder r = new StringBuilder();
		r.append("BlameResult: "); //$NON-NLS-1$
		r.append(getResultPath());
		return r.toString();
	}

	private void loadFrom(BlameGenerator gen) {
		RevCommit srcCommit = gen.getSourceCommit();
		PersonIdent srcAuthor = gen.getSourceAuthor();
		PersonIdent srcCommitter = gen.getSourceCommitter();
		String srcPath = gen.getSourcePath();
		int srcLine = gen.getSourceStart();
		int resLine = gen.getResultStart();
		int resEnd = gen.getResultEnd();

		for (; resLine < resEnd; resLine++) {
			// Reverse blame can generate multiple results for the same line.
			// Favor the first one selected, as this is the oldest and most
			// likely to be nearest to the inquiry made by the user.
			if (sourceLines[resLine] != 0)
				continue;

			sourceCommits[resLine] = srcCommit;
			sourceAuthors[resLine] = srcAuthor;
			sourceCommitters[resLine] = srcCommitter;
			sourcePaths[resLine] = srcPath;

			// Since sourceLines is 1-based to permit hasSourceData to use 0 to
			// mean the line has not been annotated yet, pre-increment instead
			// of the traditional post-increment when making the assignment.
			sourceLines[resLine] = ++srcLine;
		}
	}
}
