/*
 * Copyright (C) 2021, Luca Milanesio <luca.milanesio@gmail.com> 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.benchmarks;

import static org.eclipse.jgit.transport.ReceiveCommand.Type.CREATE;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@State(Scope.Thread)
public class GetRefsBenchmark {

	ThreadLocalRandom branchIndex = ThreadLocalRandom.current();

	@State(Scope.Benchmark)
	public static class BenchmarkState {

		@Param({ "true", "false" })
		boolean useRefTable;

		@Param({ "100", "2500", "10000", "50000" })
		int numBranches;

		@Param({ "true", "false" })
		boolean trustFolderStat;

		List<String> branches = new ArrayList<>(numBranches);

		Path testDir;

		Repository repo;

		@Setup
		@SuppressWarnings("boxing")
		public void setupBenchmark() throws IOException, GitAPIException {
			String firstBranch = "firstbranch";
			testDir = Files.createDirectory(Paths.get("testrepos"));
			String repoName = "branches-" + numBranches + "-trustFolderStat-"
					+ trustFolderStat + "-" + refDatabaseType();
			Path workDir = testDir.resolve(repoName);
			Path repoPath = workDir.resolve(".git");
			Git git = Git.init().setDirectory(workDir.toFile()).call();
			RevCommit firstCommit = git.commit().setMessage("First commit")
					.call();
			git.branchCreate().setName(firstBranch).call();

			StoredConfig cfg = git.getRepository().getConfig();
			if (useRefTable) {
				((FileRepository) git.getRepository()).convertRefStorage(
						ConfigConstants.CONFIG_REF_STORAGE_REFTABLE, false,
						false);
			} else {
				cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT,
						trustFolderStat);
			}
			cfg.setInt(ConfigConstants.CONFIG_RECEIVE_SECTION, null,
					"maxCommandBytes", Integer.MAX_VALUE);
			cfg.save();

			repo = RepositoryCache.open(RepositoryCache.FileKey
					.lenient(repoPath.toFile(), FS.DETECTED));

			System.out.println("Preparing test");
			System.out.println("- repository: \t\t" + repoPath);
			System.out.println("- refDatabase: \t\t" + refDatabaseType());
			System.out.println("- trustFolderStat: \t" + trustFolderStat);
			System.out.println("- branches: \t\t" + numBranches);

			BatchRefUpdate u = repo.getRefDatabase().newBatchUpdate();

			branches = IntStream.range(0, numBranches)
					.mapToObj(i -> "branch/" + i % 100 + "/" + i)
					.collect(Collectors.toList());
			for (String branch : branches) {
				u.addCommand(new ReceiveCommand(ObjectId.zeroId(),
						firstCommit.toObjectId(), Constants.R_HEADS + branch,
						CREATE));
			}

			System.out.println();
			System.out.print(
					String.format("Creating %d branches ... ", numBranches));

			try (RevWalk rw = new RevWalk(repo)) {
				u.execute(rw, new TextProgressMonitor());
			}
			System.out.println("DONE");
		}

		private String refDatabaseType() {
			return useRefTable ? "reftable" : "refdir";
		}

		@TearDown
		public void teardown() throws IOException {
			repo.close();
			FileUtils.delete(testDir.toFile(),
					FileUtils.RECURSIVE | FileUtils.RETRY);
		}
	}

	@Benchmark
	@BenchmarkMode({ Mode.AverageTime })
	@OutputTimeUnit(TimeUnit.MICROSECONDS)
	@Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS)
	@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.SECONDS)
	public void testGetExactRef(Blackhole blackhole, BenchmarkState state)
			throws IOException {
		String branchName = state.branches
				.get(branchIndex.nextInt(state.numBranches));
		blackhole.consume(state.repo.exactRef(branchName));
	}

	@Benchmark
	@BenchmarkMode({ Mode.AverageTime })
	@OutputTimeUnit(TimeUnit.MICROSECONDS)
	@Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS)
	@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.SECONDS)
	public void testGetRefsByPrefix(Blackhole blackhole, BenchmarkState state)
			throws IOException {
		String branchPrefix = "refs/heads/branch/" + branchIndex.nextInt(100)
				+ "/";
		blackhole.consume(
				state.repo.getRefDatabase().getRefsByPrefix(branchPrefix));
	}

	public static void main(String[] args) throws RunnerException {
		Options opt = new OptionsBuilder()
				.include(GetRefsBenchmark.class.getSimpleName())
				// .addProfiler(StackProfiler.class)
				// .addProfiler(GCProfiler.class)
				.forks(1).jvmArgs("-ea").build();
		new Runner(opt).run();
	}
}
