/*******************************************************************************
 *  Copyright (c) 2021, 2022 Hannes Wellmann and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *
 *  Contributors:
 *     Hannes Wellmann - initial API and implementation
 *     Hannes Wellmann - Bug 577116: Improve test utility method reusability
 *     Hannes Wellmann - Bug 578336 - DependencyManager: improve method-signatures and tests
 *******************************************************************************/
package org.eclipse.pde.core.tests.internal;

import static java.util.Map.entry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.pde.internal.core.DependencyManager.findRequirementsClosure;
import static org.eclipse.pde.internal.core.DependencyManager.Options.INCLUDE_ALL_FRAGMENTS;
import static org.eclipse.pde.internal.core.DependencyManager.Options.INCLUDE_NON_TEST_FRAGMENTS;
import static org.eclipse.pde.internal.core.DependencyManager.Options.INCLUDE_OPTIONAL_DEPENDENCIES;
import static org.osgi.framework.Constants.EXPORT_PACKAGE;
import static org.osgi.framework.Constants.FRAGMENT_HOST;
import static org.osgi.framework.Constants.IMPORT_PACKAGE;
import static org.osgi.framework.Constants.PROVIDE_CAPABILITY;
import static org.osgi.framework.Constants.REQUIRE_BUNDLE;
import static org.osgi.framework.Constants.REQUIRE_CAPABILITY;

import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.VersionRange;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.core.target.NameVersionDescriptor;
import org.eclipse.pde.internal.core.ClasspathComputer;
import org.eclipse.pde.internal.core.PluginModelManager;
import org.eclipse.pde.ui.tests.launcher.AbstractLaunchTest;
import org.eclipse.pde.ui.tests.util.ProjectUtils;
import org.eclipse.pde.ui.tests.util.TargetPlatformUtil;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.osgi.framework.Constants;

public class DependencyManagerTest {

	@ClassRule
	public static final TestRule RESTORE_TARGET_DEFINITION = TargetPlatformUtil.RESTORE_CURRENT_TARGET_DEFINITION_AFTER;
	@ClassRule
	public static final TestRule CLEAR_WORKSPACE = ProjectUtils.DELETE_ALL_WORKSPACE_PROJECTS_BEFORE_AND_AFTER;

	@Rule
	public final TestRule deleteCreatedTestProjectsAfter = ProjectUtils.DELETE_CREATED_WORKSPACE_PROJECTS_AFTER;
	@Rule
	public TemporaryFolder folder = new TemporaryFolder();
	private Path tpJarDirectory;

	@Before
	public void setupBefore() throws IOException {
		tpJarDirectory = folder.newFolder("TPJarDirectory").toPath();
		// ensure PluginModelManager is initialized
		PluginModelManager.getInstance().getState();
	}

	@Test
	public void testFindRequirementsClosure_requireBundle() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "1.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("1.0.0"))),

				bundle("bundle.requireBundle", "1.0.0", //
						entry(REQUIRE_BUNDLE, "bundle.a" + bundleVersion("1.0.0", "1.1.0"))));

		BundleDescription bundleA = bundleDescription("bundle.a", "1.0.0");
		BundleDescription bundle = bundleDescription("bundle.requireBundle", "1.0.0");

		Set<BundleDescription> bundles = Set.of(bundle);
		Set<BundleDescription> closure = findRequirementsClosure(bundles);
		assertThat(closure).isEqualTo(Set.of(bundleA, bundle));
	}

	@Test
	public void testFindRequirementsClosure_requireBundle2() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a1", "1.0.0"),

				bundle("bundle.a2", "1.0.0", //
						entry(REQUIRE_BUNDLE, "bundle.a1")),

				bundle("bundle.a3", "1.0.0", //
						entry(REQUIRE_BUNDLE, "bundle.a2")));

		BundleDescription bundle3 = bundleDescription("bundle.a3", "1.0.0");
		BundleDescription bundle2 = bundleDescription("bundle.a2", "1.0.0");
		BundleDescription bundle1 = bundleDescription("bundle.a1", "1.0.0");

		Set<BundleDescription> bundles = Set.of(bundle3);
		Set<BundleDescription> closure = findRequirementsClosure(bundles);
		assertThat(closure).isEqualTo(Set.of(bundle3, bundle2, bundle1));
	}

	@Test
	public void testFindRequirementsClosure_importPackage() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "2.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("2.0.0"))),

				bundle("bundle.importPackage", "1.0.0", //
						entry(IMPORT_PACKAGE, "bundle.a.pack")));

		BundleDescription bundleA = bundleDescription("bundle.a", "2.0.0");
		BundleDescription bundle = bundleDescription("bundle.importPackage", "1.0.0");

		Set<BundleDescription> bundles = Set.of(bundle);
		Set<BundleDescription> closure = findRequirementsClosure(bundles);
		assertThat(closure).isEqualTo(Set.of(bundleA, bundle));
	}

	@Test
	public void testFindRequirementsClosure_requiredCapability() throws Exception {

		setTargetPlatform( //
				bundle("capabilities.provider", "1.0.0", //
						entry(PROVIDE_CAPABILITY, "some.test.capability")),

				bundle("capabilities.consumer", "1.0.0", //
						entry(REQUIRE_CAPABILITY, "some.test.capability")));

		BundleDescription consumerDescription = bundleDescription("capabilities.consumer", "1.0.0");
		BundleDescription providerDescription = bundleDescription("capabilities.provider", "1.0.0");

		Set<BundleDescription> bundles = Set.of(consumerDescription);
		Set<BundleDescription> closure = findRequirementsClosure(bundles);
		assertThat(closure).isEqualTo(Set.of(consumerDescription, providerDescription));
	}

	@Test
	public void testFindRequirementsClosure_requireDifferentVersions() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "1.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("1.0.0"))),

				bundle("bundle.a", "2.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("2.0.0"))),

				bundle("bundle.importPackage", "1.0.0", //
						entry(IMPORT_PACKAGE, "bundle.a.pack" + version("2.0.0"))),

				bundle("bundle.requireBundle", "1.0.0", //
						entry(REQUIRE_BUNDLE, "bundle.a" + bundleVersion("1.0.0", "1.1.0"))));

		BundleDescription bundleA1 = bundleDescription("bundle.a", "1.0.0");
		BundleDescription bundleA2 = bundleDescription("bundle.a", "2.0.0");
		BundleDescription bundleImportPackage = bundleDescription("bundle.importPackage", "1.0.0");
		BundleDescription bundleRequireBundle = bundleDescription("bundle.requireBundle", "1.0.0");
		// bundleImportPackage requires bundle.a 2.0.0
		// bundleRequireBundle requires bundle.a 1.0.0

		Set<BundleDescription> bundles = Set.of(bundleImportPackage, bundleRequireBundle);
		Set<BundleDescription> closure = findRequirementsClosure(bundles);
		assertThat(closure).isEqualTo(Set.of(bundleImportPackage, bundleRequireBundle, bundleA1, bundleA2));
	}

	@Test
	public void testFindRequirementsClosure_includeFragments() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "1.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("1.0.0"))),

				bundle("bundle.fragment", "1.0.0", //
						entry(FRAGMENT_HOST, "bundle.a")));

		BundleDescription bundleA = bundleDescription("bundle.a", "1.0.0");
		BundleDescription bundleFragment = bundleDescription("bundle.fragment", "1.0.0");

		Set<BundleDescription> bundles = Set.of(bundleA);

		Set<BundleDescription> noFragmentsClosure = findRequirementsClosure(bundles);
		assertThat(noFragmentsClosure).isEqualTo(Set.of(bundleA));

		Set<BundleDescription> allFragmentsClosure = findRequirementsClosure(bundles, INCLUDE_ALL_FRAGMENTS);
		assertThat(allFragmentsClosure).isEqualTo(Set.of(bundleA, bundleFragment));
	}

	@Test
	public void testFindRequirementsClosure_includeNonTestFragments() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "1.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("1.0.0"))),

				bundle("bundle.fragment", "1.0.0", //
						entry(FRAGMENT_HOST, "bundle.a")),

				bundle("other.tests", "1.0.0", //
						entry(FRAGMENT_HOST, "bundle.a")));

		BundleDescription bundleA = bundleDescription("bundle.a", "1.0.0");
		BundleDescription bundleFragment = bundleDescription("bundle.fragment", "1.0.0");
		BundleDescription otherFragmentWithTestName = bundleDescription("other.tests", "1.0.0");

		BundleDescription testFragmentWithTestAttr = createFragmentProject("bundle.a1.tests", "bundle.a", true);
		BundleDescription testFragmentWithOtherName = createFragmentProject("bundle.a.checks", "bundle.a", true);
		BundleDescription testFragmentWithoutTestAttr = createFragmentProject("bundle.a2.tests", "bundle.a", false);

		Set<BundleDescription> bundles = Set.of(bundleA);

		Set<BundleDescription> noFragmentsClosure = findRequirementsClosure(bundles);
		assertThat(noFragmentsClosure).isEqualTo(Set.of(bundleA));

		Set<BundleDescription> allFragmentsClosure = findRequirementsClosure(bundles, INCLUDE_ALL_FRAGMENTS);
		assertThat(allFragmentsClosure).isEqualTo(Set.of(bundleA, bundleFragment, otherFragmentWithTestName,
				testFragmentWithTestAttr, testFragmentWithOtherName, testFragmentWithoutTestAttr));

		Set<BundleDescription> nonTestFragmentsClosure = findRequirementsClosure(bundles, INCLUDE_NON_TEST_FRAGMENTS);
		assertThat(nonTestFragmentsClosure)
				.isEqualTo(Set.of(bundleA, bundleFragment, otherFragmentWithTestName, testFragmentWithoutTestAttr));
	}

	@Test
	public void testFindRequirementsClosure_includeOptional() throws Exception {

		setTargetPlatform( //
				bundle("bundle.a", "1.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("1.0.0"))),

				bundle("bundle.a", "2.0.0", //
						entry(EXPORT_PACKAGE, "bundle.a.pack" + version("2.0.0"))),

				bundle("capabilities.provider", "1.0.0", //
						entry(PROVIDE_CAPABILITY, "some.test.capability")),

				bundle("bundle.optional", "1.0.0", //
						entry(IMPORT_PACKAGE, "bundle.a.pack" + version("2.0.0") + resolution(OPTIONAL)), //
						entry(REQUIRE_BUNDLE, "bundle.a" + bundleVersion("1.0.0", "1.1.0") + resolution(OPTIONAL)), //
						entry(REQUIRE_CAPABILITY, "some.test.capability" + resolution(OPTIONAL))));

		BundleDescription bundleA1 = bundleDescription("bundle.a", "1.0.0");
		BundleDescription bundleA2 = bundleDescription("bundle.a", "2.0.0");
		BundleDescription bundleProvider = bundleDescription("capabilities.provider", "1.0.0");
		BundleDescription bundleOptional = bundleDescription("bundle.optional", "1.0.0");

		Set<BundleDescription> bundles = Set.of(bundleOptional);

		Set<BundleDescription> noOptionalClosure = findRequirementsClosure(bundles);
		assertThat(noOptionalClosure).isEqualTo(Set.of(bundleOptional));

		Set<BundleDescription> optionalClosure = findRequirementsClosure(bundles, INCLUDE_OPTIONAL_DEPENDENCIES);
		assertThat(optionalClosure).isEqualTo(Set.of(bundleOptional, bundleA1, bundleA2, bundleProvider));
	}

	// --- utility methods ---

	@SafeVarargs
	private void setTargetPlatform(Map.Entry<NameVersionDescriptor, Map<String, String>>... pluginDescriptions)
			throws IOException, InterruptedException {
		TargetPlatformUtil.setDummyBundlesAsTarget(Map.ofEntries(pluginDescriptions), tpJarDirectory);
	}

	@SafeVarargs
	private static Entry<NameVersionDescriptor, Map<String, String>> bundle(String id, String version,
			Entry<String, String>... additionalManifestEntries) {
		return entry(new NameVersionDescriptor(id, version), Map.ofEntries(additionalManifestEntries));
	}

	private static String version(String version) {
		return ";" + Constants.VERSION_ATTRIBUTE + "=\"" + version + "\"";
	}

	private static String bundleVersion(String lowerBound, String upperBound) {
		return ";" + Constants.BUNDLE_VERSION_ATTRIBUTE + "=\"[" + lowerBound + "," + upperBound + ")\"";
	}

	private static String resolution(String resolutionType) {
		return ";" + Constants.RESOLUTION_DIRECTIVE + ":=\"" + resolutionType + "\"";
	}

	private static final String OPTIONAL = Constants.RESOLUTION_OPTIONAL;

	private static BundleDescription bundleDescription(String id, String version) {
		return AbstractLaunchTest.findTargetModel(id, version).getBundleDescription();
	}

	private static BundleDescription createFragmentProject(String projectName, String hostName,
			boolean setTestAttribute) throws CoreException {

		IProject project = ProjectUtils.createPluginProject(projectName, projectName, "1.0.0", (d, s) -> {
			d.setHost(s.newHost(hostName, VersionRange.emptyRange));
		});
		IPluginModelBase model = PluginRegistry.findModel(project);
		if (setTestAttribute) { // set test attribute in classpath
			IClasspathEntry[] classpath = ClasspathComputer.getClasspath(project, model, null, false, true);
			var cpEntries = Arrays.stream(classpath).map(e -> ClasspathComputer.updateTestAttribute(true, e));
			JavaCore.create(project).setRawClasspath(cpEntries.toArray(IClasspathEntry[]::new), null);
		}
		return model.getBundleDescription();
	}
}
