/*
 * Copyright (C) 2013, Christian Halstrick <christian.halstrick@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.lib;

import static org.eclipse.jgit.lib.Constants.CHARSET;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jgit.lib.RebaseTodoLine.Action;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;

/**
 * Offers methods to read and write files formatted like the git-rebase-todo
 * file
 *
 * @since 3.2
 */
public class RebaseTodoFile {
	private Repository repo;

	/**
	 * Constructor for RebaseTodoFile.
	 *
	 * @param repo
	 *            a {@link org.eclipse.jgit.lib.Repository} object.
	 */
	public RebaseTodoFile(Repository repo) {
		this.repo = repo;
	}

	/**
	 * Read a file formatted like the git-rebase-todo file. The "done" file is
	 * also formatted like the git-rebase-todo file. These files can be found in
	 * .git/rebase-merge/ or .git/rebase-append/ folders.
	 *
	 * @param path
	 *            path to the file relative to the repository's git-dir. E.g.
	 *            "rebase-merge/git-rebase-todo" or "rebase-append/done"
	 * @param includeComments
	 *            <code>true</code> if also comments should be reported
	 * @return the list of steps
	 * @throws java.io.IOException
	 */
	public List<RebaseTodoLine> readRebaseTodo(String path,
			boolean includeComments) throws IOException {
		byte[] buf = IO.readFully(new File(repo.getDirectory(), path));
		int ptr = 0;
		int tokenBegin = 0;
		List<RebaseTodoLine> r = new LinkedList<>();
		while (ptr < buf.length) {
			tokenBegin = ptr;
			ptr = RawParseUtils.nextLF(buf, ptr);
			int lineStart = tokenBegin;
			int lineEnd = ptr - 2;
			if (lineEnd >= 0 && buf[lineEnd] == '\r')
				lineEnd--;
			// Handle comments
			if (buf[tokenBegin] == '#') {
				if (includeComments)
					parseComments(buf, tokenBegin, r, lineEnd);
			} else {
				// skip leading spaces+tabs+cr
				tokenBegin = nextParsableToken(buf, tokenBegin, lineEnd);
				// Handle empty lines (maybe empty after skipping leading
				// whitespace)
				if (tokenBegin == -1) {
					if (includeComments)
						r.add(new RebaseTodoLine(RawParseUtils.decode(buf,
								lineStart, 1 + lineEnd)));
					continue;
				}
				RebaseTodoLine line = parseLine(buf, tokenBegin, lineEnd);
				if (line == null)
					continue;
				r.add(line);
			}
		}
		return r;
	}

	private static void parseComments(byte[] buf, int tokenBegin,
			List<RebaseTodoLine> r, int lineEnd) {
		RebaseTodoLine line = null;
		String commentString = RawParseUtils.decode(buf,
				tokenBegin, lineEnd + 1);
		try {
			int skip = tokenBegin + 1; // skip '#'
			skip = nextParsableToken(buf, skip, lineEnd);
			if (skip != -1) {
				// try to parse the line as non-comment
				line = parseLine(buf, skip, lineEnd);
				// successfully parsed as non-comment line
				// mark this line as a comment explicitly
				line.setAction(Action.COMMENT);
				// use the read line as comment string
				line.setComment(commentString);
			}
		} catch (Exception e) {
			// parsing as non-comment line failed
			line = null;
		} finally {
			if (line == null)
				line = new RebaseTodoLine(commentString);
			r.add(line);
		}
	}

	/**
	 * Skip leading space, tab, CR and LF characters
	 *
	 * @param buf
	 * @param tokenBegin
	 * @param lineEnd
	 * @return the token within the range of the given {@code buf} that doesn't
	 *         need to be skipped, {@code -1} if no such token found within the
	 *         range (i.e. empty line)
	 */
	private static int nextParsableToken(byte[] buf, int tokenBegin, int lineEnd) {
		while (tokenBegin <= lineEnd
				&& (buf[tokenBegin] == ' ' || buf[tokenBegin] == '\t' || buf[tokenBegin] == '\r'))
			tokenBegin++;
		if (tokenBegin > lineEnd)
			return -1;
		return tokenBegin;
	}

	private static RebaseTodoLine parseLine(byte[] buf, int tokenBegin,
			int lineEnd) {
		RebaseTodoLine.Action action = null;
		AbbreviatedObjectId commit = null;

		int nextSpace = RawParseUtils.next(buf, tokenBegin, ' ');
		int tokenCount = 0;
		while (tokenCount < 3 && nextSpace < lineEnd) {
			switch (tokenCount) {
			case 0:
				String actionToken = new String(buf, tokenBegin,
						nextSpace - tokenBegin - 1, CHARSET);
				tokenBegin = nextSpace;
				action = RebaseTodoLine.Action.parse(actionToken);
				if (action == null)
					return null; // parsing failed
				break;
			case 1:
				nextSpace = RawParseUtils.next(buf, tokenBegin, ' ');
				String commitToken = new String(buf, tokenBegin,
						nextSpace - tokenBegin - 1, CHARSET);
				tokenBegin = nextSpace;
				commit = AbbreviatedObjectId.fromString(commitToken);
				break;
			case 2:
				return new RebaseTodoLine(action, commit,
						RawParseUtils.decode(buf, tokenBegin, 1 + lineEnd));
			}
			tokenCount++;
		}
		if (tokenCount == 2)
			return new RebaseTodoLine(action, commit, ""); //$NON-NLS-1$
		return null;
	}

	/**
	 * Write a file formatted like a git-rebase-todo file.
	 *
	 * @param path
	 *            path to the file relative to the repository's git-dir. E.g.
	 *            "rebase-merge/git-rebase-todo" or "rebase-append/done"
	 * @param steps
	 *            the steps to be written
	 * @param append
	 *            whether to append to an existing file or to write a new file
	 * @throws java.io.IOException
	 */
	public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps,
			boolean append) throws IOException {
		try (OutputStream fw = new BufferedOutputStream(new FileOutputStream(
				new File(repo.getDirectory(), path), append))) {
			StringBuilder sb = new StringBuilder();
			for (RebaseTodoLine step : steps) {
				sb.setLength(0);
				if (RebaseTodoLine.Action.COMMENT.equals(step.action))
					sb.append(step.getComment());
				else {
					sb.append(step.getAction().toToken());
					sb.append(" "); //$NON-NLS-1$
					sb.append(step.getCommit().name());
					sb.append(" "); //$NON-NLS-1$
					sb.append(step.getShortMessage().trim());
				}
				sb.append('\n');
				fw.write(Constants.encode(sb.toString()));
			}
		}
	}
}
