/*******************************************************************************
 * Copyright (c) 2004, 2021 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.services.datalocation;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.tests.harness.CoreTest;
import org.eclipse.equinox.log.SynchronousLogListener;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.location.EquinoxLocations;
import org.eclipse.osgi.launch.Equinox;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogEntry;
import org.osgi.service.log.LogReaderService;
import org.osgi.util.tracker.ServiceTracker;

public class BasicLocationTests extends CoreTest {

	String prefix = "";
	boolean windows = Platform.getOS().equals(Platform.OS_WIN32);
	ServiceTracker<Location, Location> configLocationTracker = null;
	ServiceTracker<Location, Location> instanceLocationTracker = null;

	public BasicLocationTests(String name) {
		super(name);
	}

	public static Test suite() {
		return new TestSuite(BasicLocationTests.class);
	}

	protected void setUp() throws Exception {
		super.setUp();

		prefix = windows ? "c:" : "";

		configLocationTracker = new ServiceTracker<>(OSGiTestsActivator.getContext(), OSGiTestsActivator.getContext().createFilter(Location.CONFIGURATION_FILTER), null);
		instanceLocationTracker = new ServiceTracker<>(OSGiTestsActivator.getContext(), OSGiTestsActivator.getContext().createFilter(Location.INSTANCE_FILTER), null);

		configLocationTracker.open();
		instanceLocationTracker.open();
	}

	protected void tearDown() throws Exception {
		configLocationTracker.close();
		instanceLocationTracker.close();
		super.tearDown();
	}

	private void checkSlashes(Map<String, Location> locations) {
		checkLocation(locations.get(Location.USER_FILTER), true, true, null);
		checkLocation(locations.get(Location.INSTANCE_FILTER), true, true, null);
		checkLocation(locations.get(Location.CONFIGURATION_FILTER), true, true, null);
		checkLocation(locations.get(Location.INSTALL_FILTER), true, true, null);
	}

	private void checkLocation(Location location, boolean leading, boolean trailing, String scheme) {
		if (location == null)
			return;
		URL url = location.getURL();
		if (scheme != null)
			assertEquals(scheme, url.getProtocol());
		if (!url.getProtocol().equals("file"))
			return;
		assertTrue(url.toExternalForm() + " should " + (trailing ? "" : "not") + " have a trailing slash", url.getFile().endsWith("/") == trailing);
		if (windows)
			assertTrue(url.toExternalForm() + " should " + (leading ? "" : "not") + " have a leading slash", url.getFile().startsWith("/") == leading);
	}

	public void testCreateLocation01() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testCreateLocation01");
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), false);
		} catch (Throwable t) {
			fail("Failed to set location", t);
		}
		try {
			assertTrue("Could not lock location", testLocation.lock());
		} catch (IOException e) {
			fail("Failed to lock location", e);
		}
		testLocation.release();
	}

	public void testCreateLocation02() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testCreateLocation02");
		Location testLocation = configLocation.createLocation(null, null, true);
		try {
			testLocation.set(testLocationFile.toURL(), false);
		} catch (Throwable t) {
			fail("Failed to set location", t);
		}
		try {
			assertTrue("Could not lock location", testLocation.lock());
			testLocation.release();
			fail("Should not be able to lock read-only location");
		} catch (IOException e) {
			// expected
		}
	}

	public void testCreateLocation03() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testCreateLocation03");
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), true);
		} catch (Throwable t) {
			fail("Failed to set location", t);
		}
		try {
			assertTrue("Could not lock location", testLocation.isLocked());
		} catch (IOException e) {
			fail("Failed to lock location", e);
		}
		testLocation.release();
	}

	public void testCreateLocation04() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testCreateLocation04");
		Location testLocation = configLocation.createLocation(null, null, true);
		try {
			testLocation.set(testLocationFile.toURL(), true);
			testLocation.release();
			fail("Should not be able to lock read-only location");
		} catch (Throwable t) {
			// expected
		}
	}

	public void testCreateLocation05() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testCreateLocation01");
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), false);
		} catch (Throwable t) {
			fail("Failed to set location", t);
		}
		try {
			assertTrue("Could not lock location", testLocation.lock());
			assertFalse("Could lock a secend time", testLocation.lock());
			assertFalse("Could lock a third time", testLocation.lock());
		} catch (IOException e) {
			fail("Failed to lock location", e);
		} finally {
			testLocation.release();
		}
		try {
			assertTrue("Could not lock location", testLocation.lock());
		} catch (IOException e) {
			fail("Failed to lock location", e);
		} finally {
			testLocation.release();
		}
	}

	private static final String INSTANCE_DATA_AREA_PREFIX = ".metadata/.plugins/"; //$NON-NLS-1$

	public void testLocationDataArea01() {
		Location instance = instanceLocationTracker.getService();
		doAllTestLocationDataArea(instance, INSTANCE_DATA_AREA_PREFIX);

		Location configuration = configLocationTracker.getService();
		doAllTestLocationDataArea(configuration, "");
	}

	private void doAllTestLocationDataArea(Location location, String dataAreaPrefix) {
		doTestLocateDataArea(location, dataAreaPrefix, getName());
		doTestLocateDataArea(location, dataAreaPrefix, "");
		doTestLocateDataArea(location, dataAreaPrefix, "test/multiple/paths");
		doTestLocateDataArea(location, dataAreaPrefix, "test/multiple/../paths");
		doTestLocateDataArea(location, dataAreaPrefix, "test\\multiple\\paths");
		doTestLocateDataArea(location, dataAreaPrefix, "/test/begin/slash");

		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/" + getName());
		Location createdLocation = location.createLocation(null, null, false);
		try {
			createdLocation.set(testLocationFile.toURL(), false);
		} catch (Exception e) {
			fail("Failed to set location", e);
		}
		doTestLocateDataArea(createdLocation, dataAreaPrefix, getName());
		doTestLocateDataArea(createdLocation, dataAreaPrefix, "");
		doTestLocateDataArea(createdLocation, dataAreaPrefix, "test/multiple/paths");
		doTestLocateDataArea(createdLocation, dataAreaPrefix, "test/multiple/../paths");
		doTestLocateDataArea(location, dataAreaPrefix, "test\\multiple\\paths");
		doTestLocateDataArea(location, dataAreaPrefix, "/test/begin/slash");

		createdLocation = location.createLocation(null, null, false);
		try {
			createdLocation.getDataArea("shouldFail");
			fail("expected failure when location is not set");
		} catch (IOException e) {
			// expected;
		}
	}

	private void doTestLocateDataArea(Location location, String dataAreaPrefix, String namespace) {
		assertTrue("Location is not set", location.isSet());
		URL dataArea = null;
		try {
			dataArea = location.getDataArea(namespace);
		} catch (IOException e) {
			fail("Failed to get data area.", e);
		}
		assertNotNull("Data area is null.", dataArea);

		namespace = namespace.replace('\\', '/');
		if (namespace.startsWith("/")) {
			namespace = namespace.substring(1);
		}
		assertTrue("Data area is not the expected value: " + dataArea.toExternalForm(), dataArea.toExternalForm().endsWith(dataAreaPrefix + namespace));
	}

	public void testSetLocationWithEmptyLockFile() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testSetLocationWithEmptyLockFile"); //$NON-NLS-1$
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), true, ""); //$NON-NLS-1$
			// Make sure it has created the default lock file
			File lockFile = new File(testLocationFile, ".metadata/.lock"); //$NON-NLS-1$
			assertTrue("Lock file does not exist!", lockFile.exists()); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Failed to set location", t); //$NON-NLS-1$
		}
		try {
			assertTrue("Could not lock location", testLocation.isLocked()); //$NON-NLS-1$
		} catch (IOException e) {
			fail("Failed to lock location", e); //$NON-NLS-1$
		}
		testLocation.release();
	}

	public void testSetLocationWithRelLockFile() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testSetLocationWithRelLockFile"); //$NON-NLS-1$
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), true, ".mocklock"); //$NON-NLS-1$
			File lockFile = new File(testLocationFile, ".mocklock"); //$NON-NLS-1$
			assertTrue("Lock file does not exist!", lockFile.exists()); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Failed to set location", t); //$NON-NLS-1$
		}
		try {
			assertTrue("Could not lock location", testLocation.isLocked()); //$NON-NLS-1$
		} catch (IOException e) {
			fail("Failed to lock location", e); //$NON-NLS-1$
		}
		testLocation.release();
	}

	public void testSetLocationWithAbsLockFile() {
		Location configLocation = configLocationTracker.getService();
		File testLocationFile = OSGiTestsActivator.getContext().getDataFile("testLocations/testSetLocationWithAbsLockFile"); //$NON-NLS-1$
		File testLocationLockFile = OSGiTestsActivator.getContext().getDataFile("testLocations/mock.lock"); //$NON-NLS-1$
		assertTrue(testLocationLockFile.isAbsolute());
		Location testLocation = configLocation.createLocation(null, null, false);
		try {
			testLocation.set(testLocationFile.toURL(), true, testLocationLockFile.getAbsolutePath());
			assertTrue("The lock file should be present!", testLocationLockFile.exists()); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Failed to set location", t); //$NON-NLS-1$
		}
		try {
			assertTrue("Could not lock location", testLocation.isLocked()); //$NON-NLS-1$
		} catch (IOException e) {
			fail("Failed to lock location", e); //$NON-NLS-1$
		}
		testLocation.release();
		assertTrue("The lock file could not be removed!", testLocationLockFile.delete()); //$NON-NLS-1$
	}

	public void testSlashes() throws BundleException, InvalidSyntaxException {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, prefix + "/a");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, prefix + "/c/d");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, prefix + "/e/f");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			checkSlashes(getLocations(equinox));
		} finally {
			equinox.stop();
		}

	}

	private static Map<String, Location> getLocations(Equinox equinox) throws InvalidSyntaxException {
		Map<String, Location> locations = new HashMap<>();
		BundleContext context = equinox.getBundleContext();
		addLocation(context, Location.CONFIGURATION_FILTER, locations);
		addLocation(context, Location.INSTALL_FILTER, locations);
		addLocation(context, Location.INSTANCE_FILTER, locations);
		addLocation(context, Location.USER_FILTER, locations);
		return locations;
	}

	private static void addLocation(BundleContext context, String filter, Map<String, Location> locations) throws InvalidSyntaxException {
		Collection<ServiceReference<Location>> locationRefs = context.getServiceReferences(Location.class, filter);
		if (!locationRefs.isEmpty()) {
			locations.put(filter, context.getService(locationRefs.iterator().next()));
		}
	}

	public void testSchemes() throws Exception {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "http://example.com/a");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "ftp://example.com/c/d");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, "platform:/base/e/f");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			checkSlashes(locations);
			checkLocation(locations.get(Location.USER_FILTER), true, true, "http");
			checkLocation(locations.get(Location.INSTANCE_FILTER), true, true, "ftp");
			checkLocation(locations.get(Location.CONFIGURATION_FILTER), true, true, "platform");
			checkLocation(locations.get(Location.INSTALL_FILTER), true, true, "file");
		} finally {
			equinox.stop();
		}
	}

	public void testNone() throws Exception {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "@none");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "@none");
		// TODO framework does not handle no config area well
		// fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, "@none");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			assertNull("User location should be null", locations.get(Location.USER_FILTER));
			assertNull("Instance location should be null", locations.get(Location.INSTANCE_FILTER));
			// TODO assertNull("Configuration location should be null", locations.get(Location.CONFIGURATION_FILTER));
		} finally {
			equinox.stop();
		}
	}

	public void testNoDefault() throws Exception {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "@noDefault");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "@noDefault");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			Location userLocation = locations.get(Location.USER_FILTER);
			Location instanceLocation = locations.get(Location.INSTANCE_FILTER);
			assertNull("User locatoin is not null.", userLocation.getURL());
			assertNull("Instance location is not null.", instanceLocation.getURL());
		} finally {
			equinox.stop();
		}
	}

	public void testUserDir() throws Exception {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "@user.dir");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "@user.dir");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, "@user.dir");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			checkLocation(locations.get(Location.USER_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTANCE_FILTER), true, true, "file");
			checkLocation(locations.get(Location.CONFIGURATION_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTALL_FILTER), true, true, "file");
		} finally {
			equinox.stop();
		}
	}

	public void testUserHome() throws Exception {
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "@user.home");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "@user.home");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, "@user.home");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			checkLocation(locations.get(Location.USER_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTANCE_FILTER), true, true, "file");
			checkLocation(locations.get(Location.CONFIGURATION_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTALL_FILTER), true, true, "file");
		} finally {
			equinox.stop();
		}

	}

	public void testUNC() throws Exception {
		if (!windows)
			return;
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_USER_AREA, "//server/share/a");
		fwkConfig.put(EquinoxLocations.PROP_INSTANCE_AREA, "//server/share/b");
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA, "//server/share/c");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file://server/share/g");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			Map<String, Location> locations = getLocations(equinox);
			checkLocation(locations.get(Location.USER_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTANCE_FILTER), true, true, "file");
			checkLocation(locations.get(Location.CONFIGURATION_FILTER), true, true, "file");
			checkLocation(locations.get(Location.INSTALL_FILTER), true, true, "file");
		} finally {
			equinox.stop();
		}
	}

	public void testDebugLogOnGetURL() throws Exception {
		Properties debugOptions = new Properties();
		debugOptions.put("org.eclipse.osgi/debug/location", "true");
		File debugOptionsFile = OSGiTestsActivator.getContext().getDataFile(getName() + ".options");
		debugOptions.store(new FileOutputStream(debugOptionsFile), getName());
		Map<String, String> fwkConfig = new HashMap<>();
		fwkConfig.put(EquinoxLocations.PROP_CONFIG_AREA + EquinoxLocations.READ_ONLY_AREA_SUFFIX, "true");
		fwkConfig.put(EquinoxLocations.PROP_INSTALL_AREA, "file:" + prefix + "/g");
		fwkConfig.put(EquinoxConfiguration.PROP_DEBUG, debugOptionsFile.getAbsolutePath());
		fwkConfig.put("eclipse.consoleLog", "true");

		Equinox equinox = new Equinox(fwkConfig);
		equinox.init();
		try {
			final List<LogEntry> logEntries = new ArrayList<>();
			LogReaderService logReaderService = getLogReaderService(equinox);
			SynchronousLogListener logListener = entry -> logEntries.add(entry);
			logReaderService.addLogListener(logListener);
			Map<String, Location> locations = getLocations(equinox);
			Location userLocation = locations.get(Location.USER_FILTER);
			Location instanceLocation = locations.get(Location.INSTANCE_FILTER);
			assertNotNull("User locatoin is not null.", userLocation.getURL());
			assertNotNull("Instance location is not null.", instanceLocation.getURL());
			assertEquals("Wrong number of log entries", 2, logEntries.size());
		} finally {
			equinox.stop();
		}
	}

	private LogReaderService getLogReaderService(Equinox equinox) {
		return equinox.getBundleContext().getService(equinox.getBundleContext().getServiceReference(LogReaderService.class));
	}
}
