/*******************************************************************************
 * Copyright (c) 2013, 2017 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.tests.hooks.framework;

import static org.junit.Assert.assertNotEquals;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.internal.hookregistry.HookRegistry;
import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.eclipse.osgi.tests.bundles.SystemBundleTests;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.Capability;

public class StorageHookTests extends AbstractFrameworkHookTests {
	private static final String TEST_BUNDLE = "test";
	private static final String HOOK_CONFIGURATOR_BUNDLE = "storage.hooks.a";
	private static final String HOOK_CONFIGURATOR_CLASS = "org.eclipse.osgi.tests.hooks.framework.storage.a.TestHookConfigurator";
	private static final String HOOK_CONFIGURATOR_FIELD_CREATE_STORAGE_HOOK_CALLED = "createStorageHookCalled";
	private static final String HOOK_CONFIGURATOR_FIELD_FAIL_LOAD = "failLoad";
	private static final String HOOK_CONFIGURATOR_FIELD_INVALID = "invalid";
	private static final String HOOK_CONFIGURATOR_FIELD_INVALID_FACTORY_CLASS = "invalidFactoryClass";
	private static final String HOOK_CONFIGURATOR_FIELD_VALIDATE_CALLED = "validateCalled";
	private static final String HOOK_CONFIGURATOR_FIELD_DELETING_CALLED = "deletingGenerationCalled";
	private static final String HOOK_CONFIGURATOR_FIELD_ADAPT_MANIFEST = "adaptManifest";
	private static final String HOOK_CONFIGURATOR_FIELD_REPLACE_BUILDER = "replaceModuleBuilder";

	private Map<String, String> configuration;
	private Framework framework;
	private String location;

	/*
	 * Bundles must be discarded if a storage hook throws an 
	 * IllegalStateException during validation.
	 */
	public void testBundleDiscardedWhenClasspathStorageHookInvalidates() throws Exception {
		initAndStartFramework();
		installBundle();
		setStorageHookInvalid(true);
		restartFramework();
		assertStorageHookValidateCalled();
		assertBundleDiscarded();
	}

	/*
	 * Bundles must not be discarded when a storage hook says they are valid.
	 */
	public void testBundleNotDiscardedWhenClasspathStorageHookValidates() throws Exception {
		initAndStartFramework();
		installBundle();
		setStorageHookInvalid(false);
		restartFramework();
		assertStorageHookValidateCalled();
		assertBundleNotDiscarded();
	}

	/*
	 * A storage hook with the wrong factory class should cause bundle
	 * installation to fail.
	 */
	public void testWrongStorageHookFactoryClassOnBundleInstall() throws Exception {
		setFactoryClassInvalid(true);
		initAndStartFramework();
		try {
			installBundle();
			fail("Bundle install should have failed");
		} catch (BundleException e) {
			assertBundleException(e);
		}
		assertCreateStorageHookCalled();
	}

	/*
	 * A storage hook with the wrong factory class should cause bundle update
	 * to fail.
	 */
	public void testWrongStorageHookFactoryClassOnBundleUpdate() throws Exception {
		initAndStartFramework();
		installBundle();
		setFactoryClassInvalid(true);
		try {
			updateBundle();
			fail("Bundle update should have failed");
		} catch (BundleException e) {
			assertBundleException(e);
		}
		assertCreateStorageHookCalled();
	}

	/*
	 * A storage hook with the wrong factory class should cause a framework
	 * restart with persisted bundles to fail.
	 */
	public void testWrongStorageHookFactoryClassOnFrameworkRestart() throws Exception {
		initAndStartFramework();
		installBundle();
		setFactoryClassInvalid(true);
		try {
			restartFramework();
			fail("Framework restart should have failed");
		} catch (IllegalStateException e) {
			assertThrowable(e);
		}
		assertCreateStorageHookCalled();
	}

	public void testCleanOnFailLoad() throws Exception {
		initAndStartFramework();
		installBundle();
		setFactoryHookFailLoad(true);
		restartFramework();
		assertBundleDiscarded();
		// install a bundle without reference to test that the staging area is created correctly after clean
		File bundlesBase = new File(OSGiTestsActivator.getContext().getDataFile(getName()), "bundles");
		bundlesBase.mkdirs();
		framework.getBundleContext().installBundle(SystemBundleTests.createBundle(bundlesBase, getName(), false, false).toURI().toString());
	}

	public void testDeletingGenerationCalledOnDiscard() throws Exception {
		initAndStartFramework();
		installBundle();
		setStorageHookInvalid(true);
		restartFramework();
		assertStorageHookDeletingGenerationCalled();
		assertBundleDiscarded();
	}

	public void testDeletingGenerationCalledUninstall() throws Exception {
		initAndStartFramework();
		installBundle();
		Bundle b = framework.getBundleContext().getBundle(location);
		assertNotNull("Missing test bundle.", b);
		b.uninstall();
		assertStorageHookDeletingGenerationCalled();
	}

	public void testDeletingGenerationCalledUpdate() throws Exception {
		initAndStartFramework();
		installBundle();
		Bundle b = framework.getBundleContext().getBundle(location);
		assertNotNull("Missing test bundle.", b);
		b.update();
		assertStorageHookDeletingGenerationCalled();
	}

	public void testAdaptModuleRevisionBuilder() throws Exception {
		setFactoryClassAdaptManifest(true);
		initAndStartFramework();

		installBundle();
		Bundle b = framework.getBundleContext().getBundle(location);
		assertNotEquals("Wrong ID.", 5678, b.getBundleId());
		assertNotNull("Missing test bundle.", b);
		List<Capability> testCaps = b.adapt(BundleRevision.class).getCapabilities("test.file.path");
		assertEquals("Wrong number of test caps.", 1, testCaps.size());
		String path1 = (String) testCaps.get(0).getAttributes().get("test.file.path");
		assertNotNull("No path", path1);
		String operation1 = (String) testCaps.get(0).getAttributes().get("test.operation");
		assertEquals("Wrong operation", ModuleEvent.INSTALLED.toString(), operation1);
		String location1 = (String) testCaps.get(0).getAttributes().get("test.origin");
		assertEquals("Wrong origin", framework.getBundleContext().getBundle().getLocation(), location1);

		b.update();
		assertNotEquals("Wrong ID.", 5678, b.getBundleId());
		testCaps = b.adapt(BundleRevision.class).getCapabilities("test.file.path");
		assertEquals("Wrong number of test caps.", 1, testCaps.size());
		String path2 = (String) testCaps.get(0).getAttributes().get("test.file.path");
		assertNotNull("No path", path2);
		String operation2 = (String) testCaps.get(0).getAttributes().get("test.operation");
		assertEquals("Wrong operation", ModuleEvent.UPDATED.toString(), operation2);
		String location2 = (String) testCaps.get(0).getAttributes().get("test.origin");
		assertEquals("Wrong origin", location, location2);

		assertNotEquals("Path of updated bundle is the same.", path1, path2);

		framework.stop();
		framework.waitForStop(5000);

		// create new framework object to test loading of persistent capability.
		framework = createFramework(configuration);
		framework.start();
		b = framework.getBundleContext().getBundle(location);
		assertNotEquals("Wrong ID.", 5678, b.getBundleId());
		testCaps = b.adapt(BundleRevision.class).getCapabilities("test.file.path");
		assertEquals("Wrong number of test caps.", 1, testCaps.size());
		path2 = (String) testCaps.get(0).getAttributes().get("test.file.path");
		assertNotNull("No path", path2);
		operation2 = (String) testCaps.get(0).getAttributes().get("test.operation");
		assertEquals("Wrong operation", ModuleEvent.UPDATED.toString(), operation2);
		location2 = (String) testCaps.get(0).getAttributes().get("test.origin");
		assertEquals("Wrong origin", location, location2);

		setFactoryClassAdaptManifest(false);
		setFactoryClassReplaceBuilder(true);
		b.uninstall();
		installBundle();
		b = framework.getBundleContext().getBundle(location);
		assertNotEquals("Wrong ID.", 5678, b.getBundleId());
		assertNotNull("Missing test bundle.", b);
		assertEquals("Wrong BSN.", "replace", b.getSymbolicName());
		testCaps = b.adapt(BundleRevision.class).getCapabilities("replace");
		assertEquals("Wrong number of capabilities.", 1, testCaps.size());
	}

	public void testFrameworkUtilHelper() throws Exception {
		initAndStartFramework();
		Class<?> frameworkUtilClass = classLoader.loadClass("org.osgi.framework.FrameworkUtil");
		Bundle b = (Bundle) frameworkUtilClass.getMethod("getBundle", Class.class).invoke(null, BundleContext.class);
		assertEquals("Wrong bundle found.", framework.getBundleContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION), b);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		String loc = bundleInstaller.getBundleLocation(HOOK_CONFIGURATOR_BUNDLE);
		loc = loc.substring(loc.indexOf("file:"));
		classLoader.addURL(new URL(loc));
		location = bundleInstaller.getBundleLocation(TEST_BUNDLE);
		File file = OSGiTestsActivator.getContext().getDataFile(getName());
		configuration = new HashMap<String, String>();
		configuration.put(Constants.FRAMEWORK_STORAGE, file.getAbsolutePath());
		configuration.put(HookRegistry.PROP_HOOK_CONFIGURATORS_INCLUDE, HOOK_CONFIGURATOR_CLASS);
		framework = createFramework(configuration);
		resetStorageHook();
	}

	@Override
	protected void tearDown() throws Exception {
		stopQuietly(framework);
		super.tearDown();
	}

	private void assertBundleDiscarded() {
		assertBundleDiscarded(location, framework);
	}

	private void assertBundleException(BundleException e) {
		assertThrowable(e.getCause());
	}

	private void assertBundleNotDiscarded() {
		assertBundleNotDiscarded(location, framework);
	}

	private void assertCreateStorageHookCalled() throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		assertTrue("Storage hook factory createStorageHook not called by framework", clazz.getField(HOOK_CONFIGURATOR_FIELD_CREATE_STORAGE_HOOK_CALLED).getBoolean(null));
	}

	private void assertThrowable(Throwable t) {
		assertTrue("Unexpected exception", t != null && (t instanceof IllegalStateException) && t.getMessage().startsWith("The factory class "));
	}

	private void assertStorageHookValidateCalled() throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		assertTrue("Storage hook validate not called by framework", clazz.getField(HOOK_CONFIGURATOR_FIELD_VALIDATE_CALLED).getBoolean(null));
	}

	private void assertStorageHookDeletingGenerationCalled() throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		assertTrue("Storage hook deletingGeneration not called by framework", clazz.getField(HOOK_CONFIGURATOR_FIELD_DELETING_CALLED).getBoolean(null));
	}

	private void initAndStartFramework() throws Exception {
		initAndStart(framework);
	}

	private void installBundle() throws Exception {
		framework.getBundleContext().installBundle(location);
	}

	private void resetStorageHook() throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_CREATE_STORAGE_HOOK_CALLED).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_INVALID).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_VALIDATE_CALLED).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_INVALID_FACTORY_CLASS).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_DELETING_CALLED).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_ADAPT_MANIFEST).set(null, false);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_FAIL_LOAD).set(null, false);
	}

	private void restartFramework() throws Exception {
		framework = restart(framework, configuration);
	}

	private void setFactoryClassInvalid(boolean value) throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_INVALID_FACTORY_CLASS).set(null, value);
	}

	private void setStorageHookInvalid(boolean value) throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_INVALID).set(null, value);
	}

	private void setFactoryClassAdaptManifest(boolean value) throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_ADAPT_MANIFEST).set(null, value);
	}

	private void setFactoryClassReplaceBuilder(boolean value) throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_REPLACE_BUILDER).set(null, value);
	}

	private void setFactoryHookFailLoad(boolean value) throws Exception {
		Class<?> clazz = classLoader.loadClass(HOOK_CONFIGURATOR_CLASS);
		clazz.getField(HOOK_CONFIGURATOR_FIELD_FAIL_LOAD).set(null, value);
	}

	private void updateBundle() throws Exception {
		framework.getBundleContext().getBundle(location).update();
	}
}
