/*
 * Copyright (C) 2017, 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.internal.storage.reftable;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collection;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.internal.storage.io.BlockSource;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Ref;

/** Abstract table of references. */
public abstract class Reftable implements AutoCloseable {
	/**
	 * @param refs
	 *            references to convert into a reftable; may be empty.
	 * @return a reader for the supplied references.
	 */
	public static Reftable from(Collection<Ref> refs) {
		try {
			ReftableConfig cfg = new ReftableConfig();
			cfg.setIndexObjects(false);
			cfg.setAlignBlocks(false);
			ByteArrayOutputStream buf = new ByteArrayOutputStream();
			new ReftableWriter()
				.setConfig(cfg)
				.begin(buf)
				.sortAndWriteRefs(refs)
				.finish();
			return new ReftableReader(BlockSource.from(buf.toByteArray()));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/** {@code true} if deletions should be included in results. */
	protected boolean includeDeletes;

	/**
	 * @param deletes
	 *            if {@code true} deleted references will be returned. If
	 *            {@code false} (default behavior), deleted references will be
	 *            skipped, and not returned.
	 */
	public void setIncludeDeletes(boolean deletes) {
		includeDeletes = deletes;
	}

	/**
	 * Seek to the first reference, to iterate in order.
	 *
	 * @return cursor to iterate.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	public abstract RefCursor allRefs() throws IOException;

	/**
	 * Seek either to a reference, or a reference subtree.
	 * <p>
	 * If {@code refName} ends with {@code "/"} the method will seek to the
	 * subtree of all references starting with {@code refName} as a prefix. If
	 * no references start with this prefix, an empty cursor is returned.
	 * <p>
	 * Otherwise exactly {@code refName} will be looked for. If present, the
	 * returned cursor will iterate exactly one entry. If not found, an empty
	 * cursor is returned.
	 *
	 * @param refName
	 *            reference name or subtree to find.
	 * @return cursor to iterate; empty cursor if no references match.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	public abstract RefCursor seekRef(String refName) throws IOException;

	/**
	 * Match references pointing to a specific object.
	 *
	 * @param id
	 *            object to find.
	 * @return cursor to iterate; empty cursor if no references match.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	public abstract RefCursor byObjectId(AnyObjectId id) throws IOException;

	/**
	 * Seek reader to read log records.
	 *
	 * @return cursor to iterate; empty cursor if no logs are present.
	 * @throws IOException
	 *             if logs cannot be read.
	 */
	public abstract LogCursor allLogs() throws IOException;

	/**
	 * Read a single reference's log.
	 *
	 * @param refName
	 *            exact name of the reference whose log to read.
	 * @return cursor to iterate; empty cursor if no logs match.
	 * @throws IOException
	 *             if logs cannot be read.
	 */
	public LogCursor seekLog(String refName) throws IOException {
		return seekLog(refName, Long.MAX_VALUE);
	}

	/**
	 * Seek to an update index in a reference's log.
	 *
	 * @param refName
	 *            exact name of the reference whose log to read.
	 * @param updateIndex
	 *            most recent index to return first in the log cursor. Log
	 *            records at or before {@code updateIndex} will be returned.
	 * @return cursor to iterate; empty cursor if no logs match.
	 * @throws IOException
	 *             if logs cannot be read.
	 */
	public abstract LogCursor seekLog(String refName, long updateIndex)
			throws IOException;

	/**
	 * Lookup a reference, or null if not found.
	 *
	 * @param refName
	 *            reference name to find.
	 * @return the reference, or {@code null} if not found.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	@Nullable
	public Ref exactRef(String refName) throws IOException {
		try (RefCursor rc = seekRef(refName)) {
			return rc.next() ? rc.getRef() : null;
		}
	}

	/**
	 * Test if a reference or reference subtree exists.
	 * <p>
	 * If {@code refName} ends with {@code "/"}, the method tests if any
	 * reference starts with {@code refName} as a prefix.
	 * <p>
	 * Otherwise, the method checks if {@code refName} exists.
	 *
	 * @param refName
	 *            reference name or subtree to find.
	 * @return {@code true} if the reference exists, or at least one reference
	 *         exists in the subtree.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	public boolean hasRef(String refName) throws IOException {
		try (RefCursor rc = seekRef(refName)) {
			return rc.next();
		}
	}

	/**
	 * Test if any reference directly refers to the object.
	 *
	 * @param id
	 *            ObjectId to find.
	 * @return {@code true} if any reference exists directly referencing
	 *         {@code id}, or a annotated tag that peels to {@code id}.
	 * @throws IOException
	 *             if references cannot be read.
	 */
	public boolean hasId(AnyObjectId id) throws IOException {
		try (RefCursor rc = byObjectId(id)) {
			return rc.next();
		}
	}

	@Override
	public abstract void close() throws IOException;
}
