/*
 * 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;

	/**
	 * Get next update index
	 *
	 * @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();
		}
	}

	/**
	 * Get ReflogReader
	 *
	 * @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();
		}
	}

	/**
	 * Create a ReceiveCommand for the change from oldRef to newRef
	 *
	 * @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();
	}

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

	/**
	 * Get reader for merged reftable
	 *
	 * @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;
	}

	/**
	 * Whether refName is conflicting
	 *
	 * @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 excludes}.
	 * @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);
	}

	/**
	 * Whether there is a fast SHA1 to ref map
	 *
	 * @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();
		}
	}
}
