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

import static org.eclipse.jgit.lib.Constants.encodeASCII;
import static org.eclipse.jgit.util.RawParseUtils.match;
import static org.eclipse.jgit.util.RawParseUtils.nextLF;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.FileMode;

/**
 * A file in the Git "diff --cc" or "diff --combined" format.
 * <p>
 * A combined diff shows an n-way comparison between two or more ancestors and
 * the final revision. Its primary function is to perform code reviews on a
 * merge which introduces changes not in any ancestor.
 */
public class CombinedFileHeader extends FileHeader {
	private static final byte[] MODE = encodeASCII("mode ");

	private AbbreviatedObjectId[] oldIds;

	private FileMode[] oldModes;

	CombinedFileHeader(final byte[] b, final int offset) {
		super(b, offset);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<? extends CombinedHunkHeader> getHunks() {
		return (List<CombinedHunkHeader>) super.getHunks();
	}

	/** @return number of ancestor revisions mentioned in this diff. */
	@Override
	public int getParentCount() {
		return oldIds.length;
	}

	/** @return get the file mode of the first parent. */
	@Override
	public FileMode getOldMode() {
		return getOldMode(0);
	}

	/**
	 * Get the file mode of the nth ancestor
	 *
	 * @param nthParent
	 *            the ancestor to get the mode of
	 * @return the mode of the requested ancestor.
	 */
	public FileMode getOldMode(final int nthParent) {
		return oldModes[nthParent];
	}

	/** @return get the object id of the first parent. */
	@Override
	public AbbreviatedObjectId getOldId() {
		return getOldId(0);
	}

	/**
	 * Get the ObjectId of the nth ancestor
	 *
	 * @param nthParent
	 *            the ancestor to get the object id of
	 * @return the id of the requested ancestor.
	 */
	public AbbreviatedObjectId getOldId(final int nthParent) {
		return oldIds[nthParent];
	}

	@Override
	public String getScriptText(final Charset ocs, final Charset ncs) {
		final Charset[] cs = new Charset[getParentCount() + 1];
		Arrays.fill(cs, ocs);
		cs[getParentCount()] = ncs;
		return getScriptText(cs);
	}

	/**
	 * Convert the patch script for this file into a string.
	 *
	 * @param charsetGuess
	 *            optional array to suggest the character set to use when
	 *            decoding each file's line. If supplied the array must have a
	 *            length of <code>{@link #getParentCount()} + 1</code>
	 *            representing the old revision character sets and the new
	 *            revision character set.
	 * @return the patch script, as a Unicode string.
	 */
	@Override
	public String getScriptText(final Charset[] charsetGuess) {
		return super.getScriptText(charsetGuess);
	}

	@Override
	int parseGitHeaders(int ptr, final int end) {
		while (ptr < end) {
			final int eol = nextLF(buf, ptr);
			if (isHunkHdr(buf, ptr, end) >= 1) {
				// First hunk header; break out and parse them later.
				break;

			} else if (match(buf, ptr, OLD_NAME) >= 0) {
				parseOldName(ptr, eol);

			} else if (match(buf, ptr, NEW_NAME) >= 0) {
				parseNewName(ptr, eol);

			} else if (match(buf, ptr, INDEX) >= 0) {
				parseIndexLine(ptr + INDEX.length, eol);

			} else if (match(buf, ptr, MODE) >= 0) {
				parseModeLine(ptr + MODE.length, eol);

			} else if (match(buf, ptr, NEW_FILE_MODE) >= 0) {
				parseNewFileMode(ptr, eol);

			} else if (match(buf, ptr, DELETED_FILE_MODE) >= 0) {
				parseDeletedFileMode(ptr + DELETED_FILE_MODE.length, eol);

			} else {
				// Probably an empty patch (stat dirty).
				break;
			}

			ptr = eol;
		}
		return ptr;
	}

	@Override
	protected void parseIndexLine(int ptr, final int eol) {
		// "index $asha1,$bsha1..$csha1"
		//
		final List<AbbreviatedObjectId> ids = new ArrayList<AbbreviatedObjectId>();
		while (ptr < eol) {
			final int comma = nextLF(buf, ptr, ',');
			if (eol <= comma)
				break;
			ids.add(AbbreviatedObjectId.fromString(buf, ptr, comma - 1));
			ptr = comma;
		}

		oldIds = new AbbreviatedObjectId[ids.size() + 1];
		ids.toArray(oldIds);
		final int dot2 = nextLF(buf, ptr, '.');
		oldIds[ids.size()] = AbbreviatedObjectId.fromString(buf, ptr, dot2 - 1);
		newId = AbbreviatedObjectId.fromString(buf, dot2 + 1, eol - 1);
		oldModes = new FileMode[oldIds.length];
	}

	@Override
	protected void parseNewFileMode(final int ptr, final int eol) {
		for (int i = 0; i < oldModes.length; i++)
			oldModes[i] = FileMode.MISSING;
		super.parseNewFileMode(ptr, eol);
	}

	@Override
	HunkHeader newHunkHeader(final int offset) {
		return new CombinedHunkHeader(this, offset);
	}

	private void parseModeLine(int ptr, final int eol) {
		// "mode $amode,$bmode..$cmode"
		//
		int n = 0;
		while (ptr < eol) {
			final int comma = nextLF(buf, ptr, ',');
			if (eol <= comma)
				break;
			oldModes[n++] = parseFileMode(ptr, comma);
			ptr = comma;
		}
		final int dot2 = nextLF(buf, ptr, '.');
		oldModes[n] = parseFileMode(ptr, dot2);
		newMode = parseFileMode(dot2 + 1, eol);
	}

	private void parseDeletedFileMode(int ptr, final int eol) {
		// "deleted file mode $amode,$bmode"
		//
		changeType = ChangeType.DELETE;
		int n = 0;
		while (ptr < eol) {
			final int comma = nextLF(buf, ptr, ',');
			if (eol <= comma)
				break;
			oldModes[n++] = parseFileMode(ptr, comma);
			ptr = comma;
		}
		oldModes[n] = parseFileMode(ptr, eol);
		newMode = FileMode.MISSING;
	}
}
