/*
 * Copyright (C) 2022, Tencent.
 *
 * 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.file;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphFormatException;
import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphLoader;
import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
import org.eclipse.jgit.lib.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Traditional file system for commit-graph.
 * <p>
 * This is the commit-graph file representation for a Git object database. Each
 * call to {@link FileCommitGraph#get()} will recheck for newer versions.
 */
public class FileCommitGraph {
	private final static Logger LOG = LoggerFactory
			.getLogger(FileCommitGraph.class);

	private final AtomicReference<GraphSnapshot> baseGraph;

	/**
	 * Initialize a reference to an on-disk commit-graph.
	 *
	 * @param objectsDir
	 *            the location of the <code>objects</code> directory.
	 */
	FileCommitGraph(File objectsDir) {
		this.baseGraph = new AtomicReference<>(new GraphSnapshot(
				new File(objectsDir, Constants.INFO_COMMIT_GRAPH)));
	}

	/**
	 * The method will first scan whether the ".git/objects/info/commit-graph"
	 * has been modified, if so, it will re-parse the file, otherwise it will
	 * return the same result as the last time.
	 *
	 * @return commit-graph or null if commit-graph file does not exist or
	 *         corrupt.
	 */
	CommitGraph get() {
		GraphSnapshot original = baseGraph.get();
		synchronized (baseGraph) {
			GraphSnapshot o, n;
			do {
				o = baseGraph.get();
				if (o != original) {
					// Another thread did the scan for us, while we
					// were blocked on the monitor above.
					//
					return o.getCommitGraph();
				}
				n = o.refresh();
				if (n == o) {
					return n.getCommitGraph();
				}
			} while (!baseGraph.compareAndSet(o, n));
			return n.getCommitGraph();
		}
	}

	private static final class GraphSnapshot {
		private final File file;

		private final FileSnapshot snapshot;

		private final CommitGraph graph;

		GraphSnapshot(@NonNull File file) {
			this(file, null, null);
		}

		GraphSnapshot(@NonNull File file, FileSnapshot snapshot,
				CommitGraph graph) {
			this.file = file;
			this.snapshot = snapshot;
			this.graph = graph;
		}

		CommitGraph getCommitGraph() {
			return graph;
		}

		GraphSnapshot refresh() {
			if (graph == null && !file.exists()) {
				// commit-graph file didn't exist
				return this;
			}
			if (snapshot != null && !snapshot.isModified(file)) {
				// commit-graph file was not modified
				return this;
			}
			return new GraphSnapshot(file, FileSnapshot.save(file), open(file));
		}

		private static CommitGraph open(File file) {
			try {
				return CommitGraphLoader.open(file);
			} catch (FileNotFoundException noFile) {
				// ignore if file do not exist
				return null;
			} catch (IOException e) {
				if (e instanceof CommitGraphFormatException) {
					LOG.warn(
							MessageFormat.format(
									JGitText.get().corruptCommitGraph, file),
							e);
				} else {
					LOG.error(MessageFormat.format(
							JGitText.get().exceptionWhileLoadingCommitGraph,
							file), e);
				}
				return null;
			}
		}
	}
}
