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

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.transport.ReceiveCommand;

/**
 * Operations on {@link MergedReftable} that is common to various reftable-using
 * subclasses of {@link RefDatabase}. See
 * {@link org.eclipse.jgit.internal.storage.dfs.DfsReftableDatabase} for an
 * example.
 */
public abstract class ReftableDatabase {
	// Protects mergedTables.
	private final ReentrantLock lock = new ReentrantLock(true);

	private Reftable mergedTables;

	/**
	 * ReftableDatabase lazily initializes its merged reftable on the first read after
	 * construction or clearCache() call. This function should always instantiate a new
	 * MergedReftable based on the list of reftables specified by the underlying storage.
	 *
	 * @return the ReftableStack for this instance
	 * @throws IOException
	 *             on I/O problems.
	 */
	protected abstract MergedReftable openMergedReftable() throws IOException;

	/**
	 * @return the next available logical timestamp for an additional reftable
	 *         in the stack.
	 * @throws java.io.IOException
	 *             on I/O problems.
	 */
	public long nextUpdateIndex() throws IOException {
		lock.lock();
		try {
			return reader().maxUpdateIndex() + 1;
		} finally {
			lock.unlock();
		}
	}

	/**
	 * @return a ReflogReader for the given ref
	 * @param refname
	 *            the name of the ref.
	 * @throws IOException
	 *             on I/O problems
	 */
	public ReflogReader getReflogReader(String refname) throws IOException {
		lock.lock();
		try {
			return new ReftableReflogReader(lock, reader(), refname);
		} finally {
			lock.unlock();
		}
	}

	/**
	 * @return a ReceiveCommand for the change from oldRef to newRef
	 * @param oldRef
	 *            a ref
	 * @param newRef
	 *            a ref
	 */
	public static ReceiveCommand toCommand(Ref oldRef, Ref newRef) {
		ObjectId oldId = toId(oldRef);
		ObjectId newId = toId(newRef);
		String name = oldRef != null ? oldRef.getName() : newRef.getName();

		if (oldRef != null && oldRef.isSymbolic()) {
			if (newRef != null) {
				if (newRef.isSymbolic()) {
					return ReceiveCommand.link(oldRef.getTarget().getName(),
							newRef.getTarget().getName(), name);
				}
				// This should pass in oldId for compat with
				// RefDirectoryUpdate
				return ReceiveCommand.unlink(oldRef.getTarget().getName(),
						newId, name);
			}
			return ReceiveCommand.unlink(oldRef.getTarget().getName(),
					ObjectId.zeroId(), name);
		}

		if (newRef != null && newRef.isSymbolic()) {
			if (oldRef != null) {
				if (oldRef.isSymbolic()) {
					return ReceiveCommand.link(oldRef.getTarget().getName(),
							newRef.getTarget().getName(), name);
				}
				return ReceiveCommand.link(oldId,
						newRef.getTarget().getName(), name);
			}
			return ReceiveCommand.link(ObjectId.zeroId(),
					newRef.getTarget().getName(), name);
		}

		return new ReceiveCommand(oldId, newId, name);
	}

	private static ObjectId toId(Ref ref) {
		if (ref != null) {
			ObjectId id = ref.getObjectId();
			if (id != null) {
				return id;
			}
		}
		return ObjectId.zeroId();
	}

	/**
	 * @return the lock protecting underlying ReftableReaders against concurrent
	 *         reads.
	 */
	public ReentrantLock getLock() {
		return lock;
	}

	/**
	 * @return the merged reftable that is implemented by the stack of
	 *         reftables. Return value must be accessed under lock.
	 * @throws IOException
	 *             on I/O problems
	 */
	private Reftable reader() throws IOException {
		if (!lock.isLocked()) {
			throw new IllegalStateException(
					"must hold lock to access merged table"); //$NON-NLS-1$
		}
		if (mergedTables == null) {
			mergedTables = openMergedReftable();
		}
		return mergedTables;
	}

	/**
	 * @return whether the given refName would be illegal in a repository that
	 *         uses loose refs.
	 * @param refName
	 *            the name to check
	 * @param added
	 *            a sorted set of refs we pretend have been added to the
	 *            database.
	 * @param deleted
	 *            a set of refs we pretend have been removed from the database.
	 * @throws IOException
	 *             on I/O problems
	 */
	public boolean isNameConflicting(String refName, TreeSet<String> added,
			Set<String> deleted) throws IOException {
		lock.lock();
		try {
			Reftable table = reader();

			// Cannot be nested within an existing reference.
			int lastSlash = refName.lastIndexOf('/');
			while (0 < lastSlash) {
				String prefix = refName.substring(0, lastSlash);
				if (!deleted.contains(prefix)
						&& (table.hasRef(prefix) || added.contains(prefix))) {
					return true;
				}
				lastSlash = refName.lastIndexOf('/', lastSlash - 1);
			}

			// Cannot be the container of an existing reference.
			String prefix = refName + '/';
			RefCursor c = table.seekRefsWithPrefix(prefix);
			while (c.next()) {
				if (!deleted.contains(c.getRef().getName())) {
					return true;
				}
			}

			String it = added.ceiling(refName + '/');
			if (it != null && it.startsWith(prefix)) {
				return true;
			}
			return false;
		} finally {
			lock.unlock();
		}
	}

	/**
	 * Read a single reference.
	 * <p>
	 * This method expects an unshortened reference name and does not search
	 * using the standard search path.
	 *
	 * @param name
	 *            the unabbreviated name of the reference.
	 * @return the reference (if it exists); else {@code null}.
	 * @throws java.io.IOException
	 *             the reference space cannot be accessed.
	 */
	@Nullable
	public Ref exactRef(String name) throws IOException {
		lock.lock();
		try {
			Reftable table = reader();
			Ref ref = table.exactRef(name);
			if (ref != null && ref.isSymbolic()) {
				return table.resolve(ref);
			}
			return ref;
		} finally {
			lock.unlock();
		}
	}

	/**
	 * Returns refs whose names start with a given prefix.
	 *
	 * @param prefix
	 *            string that names of refs should start with; may be empty (to
	 *            return all refs).
	 * @return immutable list of refs whose names start with {@code prefix}.
	 * @throws java.io.IOException
	 *             the reference space cannot be accessed.
	 */
	public List<Ref> getRefsByPrefix(String prefix) throws IOException {
		List<Ref> all = new ArrayList<>();
		lock.lock();
		try {
			Reftable table = reader();
			try (RefCursor rc = RefDatabase.ALL.equals(prefix) ? table.allRefs()
					: table.seekRefsWithPrefix(prefix)) {
				while (rc.next()) {
					Ref ref = table.resolve(rc.getRef());
					if (ref != null && ref.getObjectId() != null) {
						all.add(ref);
					}
				}
			}
		} finally {
			lock.unlock();
		}

		return Collections.unmodifiableList(all);
	}

	/**
	 * Returns refs whose names start with a given prefix excluding all refs that
	 * start with one of the given prefixes.
	 *
	 * @param include string that names of refs should start with; may be empty.
	 * @param excludes strings that names of refs can't start with; may be empty.
	 * @return immutable list of refs whose names start with {@code include} and
	 *         none of the strings in {@code exclude}.
	 * @throws java.io.IOException the reference space cannot be accessed.
	 */
	public List<Ref> getRefsByPrefixWithExclusions(String include, Set<String> excludes) throws IOException {
		if (excludes.isEmpty()) {
			return getRefsByPrefix(include);
		}
		List<Ref> results = new ArrayList<>();
		lock.lock();
		try {
			Reftable table = reader();
			Iterator<String> excludeIterator =
					excludes.stream().sorted().collect(Collectors.toList()).iterator();
			String currentExclusion = excludeIterator.hasNext() ? excludeIterator.next() : null;
			try (RefCursor rc = RefDatabase.ALL.equals(include) ? table.allRefs() : table.seekRefsWithPrefix(include)) {
				while (rc.next()) {
					Ref ref = table.resolve(rc.getRef());
					if (ref == null || ref.getObjectId() == null) {
						continue;
					}
					// Skip prefixes that will never see since we are already further than those
					// prefixes lexicographically.
					while (excludeIterator.hasNext() && !ref.getName().startsWith(currentExclusion)
							&& ref.getName().compareTo(currentExclusion) > 0) {
						currentExclusion = excludeIterator.next();
					}

					if (currentExclusion != null && ref.getName().startsWith(currentExclusion)) {
						rc.seekPastPrefix(currentExclusion);
						continue;
					}
					results.add(ref);
				}
			}
		} finally {
			lock.unlock();
		}

		return Collections.unmodifiableList(results);
	}

	/**
	 * @return whether there is a fast SHA1 to ref map.
	 * @throws IOException in case of I/O problems.
	 */
	public boolean hasFastTipsWithSha1() throws IOException {
		lock.lock();
		try {
			return reader().hasObjectMap();
		} finally {
			lock.unlock();
		}
	}

	/**
	 * Returns all refs that resolve directly to the given {@link ObjectId}.
	 * Includes peeled {@link ObjectId}s.
	 *
	 * @param id
	 *            {@link ObjectId} to resolve
	 * @return a {@link Set} of {@link Ref}s whose tips point to the provided
	 *         id.
	 * @throws java.io.IOException
	 *             on I/O errors.
	 */
	public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
		lock.lock();
		try {
			RefCursor cursor = reader().byObjectId(id);
			Set<Ref> refs = new HashSet<>();
			while (cursor.next()) {
				refs.add(cursor.getRef());
			}
			return refs;
		} finally {
			lock.unlock();
		}
	}

	/**
	 * Drops all data that might be cached in memory.
	 */
	public void clearCache() {
		lock.lock();
		try {
			mergedTables = null;
		} finally {
			lock.unlock();
		}
	}
}
