/*
 * Copyright (c) 2019, 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
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.transport.internal;

import java.io.IOException;
import java.util.Set;

import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdSubclassMap;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.revwalk.ObjectWalk;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.transport.ConnectivityChecker;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceiveCommand.Result;

/**
 * A connectivity checker that uses the entire reference database to perform
 * reachability checks when checking the connectivity of objects. If
 * info.isCheckObjects() is set it will also check that objects referenced by
 * deltas are either provided or reachable as well.
 */
public final class FullConnectivityChecker implements ConnectivityChecker {
	@Override
	public void checkConnectivity(ConnectivityCheckInfo connectivityCheckInfo,
			Set<ObjectId> haves, ProgressMonitor pm)
			throws MissingObjectException, IOException {
		pm.beginTask(JGitText.get().countingObjects,
				ProgressMonitor.UNKNOWN);
		try (ObjectWalk ow = new ObjectWalk(connectivityCheckInfo.getRepository())) {
			if (!markStartAndKnownNodes(connectivityCheckInfo, ow, haves,
					pm)) {
				return;
			}
			checkCommitTree(connectivityCheckInfo, ow, pm);
			checkObjects(connectivityCheckInfo, ow, pm);
		} finally {
			pm.endTask();
		}
	}

	/**
	 * @param connectivityCheckInfo
	 *            Source for connectivity check.
	 * @param ow
	 *            Walk which can also check blobs.
	 * @param haves
	 *            Set of references known for client.
	 * @param pm
	 *            Monitor to publish progress to.
	 * @return true if at least one new node was marked.
	 * @throws IOException
	 *             an error occurred during connectivity checking.
	 */
	private boolean markStartAndKnownNodes(
			ConnectivityCheckInfo connectivityCheckInfo,
			ObjectWalk ow,
			Set<ObjectId> haves, ProgressMonitor pm)
			throws IOException {
		boolean markTrees = connectivityCheckInfo
				.isCheckObjects()
				&& !connectivityCheckInfo.getParser().getBaseObjectIds()
						.isEmpty();
		if (connectivityCheckInfo.isCheckObjects()) {
			ow.sort(RevSort.TOPO);
			if (!connectivityCheckInfo.getParser().getBaseObjectIds()
					.isEmpty()) {
				ow.sort(RevSort.BOUNDARY, true);
			}
		}
		boolean hasInteresting = false;

		for (ReceiveCommand cmd : connectivityCheckInfo.getCommands()) {
			if (cmd.getResult() != Result.NOT_ATTEMPTED) {
				continue;
			}
			if (cmd.getType() == ReceiveCommand.Type.DELETE) {
				continue;
			}
			if (haves.contains(cmd.getNewId())) {
				continue;
			}
			ow.markStart(ow.parseAny(cmd.getNewId()));
			pm.update(1);
			hasInteresting = true;
		}
		if (!hasInteresting) {
			return false;
		}
		for (ObjectId have : haves) {
			RevObject o = ow.parseAny(have);
			ow.markUninteresting(o);
			pm.update(1);

			if (markTrees) {
				o = ow.peel(o);
				if (o instanceof RevCommit) {
					o = ((RevCommit) o).getTree();
				}
				if (o instanceof RevTree) {
					ow.markUninteresting(o);
				}
			}
		}
		return true;
	}

	/**
	 * @param connectivityCheckInfo
	 *            Source for connectivity check.
	 * @param ow
	 *            Walk which can also check blobs.
	 * @param pm
	 *            Monitor to publish progress to.
	 * @throws IOException
	 *             an error occurred during connectivity checking.
	 */
	private void checkCommitTree(ConnectivityCheckInfo connectivityCheckInfo,
			ObjectWalk ow,
			ProgressMonitor pm) throws IOException {
		RevCommit c;
		ObjectIdSubclassMap<ObjectId> newObjectIds = connectivityCheckInfo
				.getParser()
				.getNewObjectIds();
		while ((c = ow.next()) != null) {
			pm.update(1);
			if (connectivityCheckInfo.isCheckObjects()
					&& !c.has(RevFlag.UNINTERESTING)
					&& !newObjectIds.contains(c)) {
				throw new MissingObjectException(c, Constants.TYPE_COMMIT);
			}
		}
	}

	/**
	 * @param connectivityCheckInfo
	 *            Source for connectivity check.
	 * @param ow
	 *            Walk which can also check blobs.
	 * @param pm
	 *            Monitor to publish progress to.
	 * @throws IOException
	 *             an error occurred during connectivity checking.
	 *
	 */
	private void checkObjects(ConnectivityCheckInfo connectivityCheckInfo,
			ObjectWalk ow,
			ProgressMonitor pm) throws IOException {
		RevObject o;
		ObjectIdSubclassMap<ObjectId> newObjectIds = connectivityCheckInfo
				.getParser()
				.getNewObjectIds();

		while ((o = ow.nextObject()) != null) {
			pm.update(1);
			if (o.has(RevFlag.UNINTERESTING)) {
				continue;
			}

			if (connectivityCheckInfo.isCheckObjects()) {
				if (newObjectIds.contains(o)) {
					continue;
				}
				throw new MissingObjectException(o, o.getType());

			}

			if (o instanceof RevBlob
					&& !connectivityCheckInfo.getRepository().getObjectDatabase()
							.has(o)) {
				throw new MissingObjectException(o, Constants.TYPE_BLOB);
			}
		}

		if (connectivityCheckInfo.isCheckObjects()) {
			for (ObjectId id : connectivityCheckInfo.getParser()
					.getBaseObjectIds()) {
				o = ow.parseAny(id);
				if (!o.has(RevFlag.UNINTERESTING)) {
					throw new MissingObjectException(o, o.getType());
				}
			}
		}
	}
}
