/*******************************************************************************
 * Copyright (c) 2018 SAP SE and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAP SE - initial version
 *******************************************************************************/
package org.eclipse.urischeme.internal.registration;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.urischeme.IOperatingSystemRegistration;
import org.eclipse.urischeme.IScheme;
import org.eclipse.urischeme.ISchemeInformation;
import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestUnitRegistrationLinux {

	private static final String PRODUCT_NAME = "myProduct";
	private static final String USER_HOME = System.getProperty("user.home");
	private static final String ECLIPSE_LAUNCHER = "eclipse.launcher";
	private static final String ECLIPSE_HOME_LOCATION = "eclipse.home.location";
	private  static final String OTHER_APP_EXECUTABLE_PATH = "/home/myuser/otherApp/app";
	private static final String OTHER_APP_DESKTOP_FILE = "otherApp.desktop";
	private static final String PATH_OTHER_APP_DESKTOP_FILE = USER_HOME + "/.local/share/applications/"
			+ OTHER_APP_DESKTOP_FILE;

	private static final String OWN_EXECUTABLE_PATH = "/home/myuser/Eclipse/Eclipse";
	private static final String OWN_DESKTOP_FILE = "_home_myuser_Eclipse_.desktop";
	private static final String PATH_OWN_DESKTOP_FILE = USER_HOME + "/.local/share/applications/" + OWN_DESKTOP_FILE;

	private static final IScheme ADT_SCHEME = new Scheme("adt", "");

	private static final ISchemeInformation OTHER_SCHEME_INFO = new SchemeInformation("other", "");
	private static final ISchemeInformation ADT_SCHEME_INFO = new SchemeInformation("adt", "");

	private static String originalEclipseHomeLocation;
	private static String originalEclipseLauncher;

	private IOperatingSystemRegistration registration;

	private FileProviderMock fileProvider;
	private ProcessSpy processStub;

	@Before
	public void setup() {
		fileProvider = new FileProviderMock();
		processStub = new ProcessSpy();

		System.setProperty(ECLIPSE_HOME_LOCATION, "file:/home/myuser/Eclipse/");
		System.setProperty(ECLIPSE_LAUNCHER, "/home/myuser/Eclipse/Eclipse");

		registration = new RegistrationLinux(fileProvider, processStub, PRODUCT_NAME);
	}

	@BeforeClass
	public static void classSetup() {
		originalEclipseHomeLocation = System.getProperty(ECLIPSE_HOME_LOCATION, "");
		originalEclipseLauncher = System.getProperty(ECLIPSE_LAUNCHER, "");
	}

	@AfterClass
	public static void classTearDown() {
		System.setProperty(ECLIPSE_HOME_LOCATION, originalEclipseHomeLocation);
		System.setProperty(ECLIPSE_LAUNCHER, originalEclipseLauncher);
	}

	@Test
	public void handlesAddOnly() throws Exception {
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE, getFileLines(OWN_EXECUTABLE_PATH, ""));

		registration.handleSchemes(Arrays.asList(ADT_SCHEME_INFO), Collections.emptyList());

		assertFilePathIs(PATH_OWN_DESKTOP_FILE);

		assertMimeTypeInFileIs("x-scheme-handler/adt;");

		assertXdgMimeCalledFor("x-scheme-handler/adt");
	}

	@Test
	public void handlesAddAndRemoveAtOnce() throws Exception {
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE,
				getFileLines(OWN_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		registration.handleSchemes(Arrays.asList(OTHER_SCHEME_INFO), Arrays.asList(ADT_SCHEME_INFO));

		assertFilePathIs(PATH_OWN_DESKTOP_FILE);

		assertMimeTypeInFileIs("x-scheme-handler/other;");

		assertXdgMimeCalledFor("x-scheme-handler/other");
	}

	@Test
	public void handlesRemoveOnly() throws Exception {
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE,
				getFileLines(OWN_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		registration.handleSchemes(Collections.emptyList(), Arrays.asList(ADT_SCHEME_INFO));

		assertFilePathIs(PATH_OWN_DESKTOP_FILE);

		assertNoMimeTypeInFile();

		assertTrue(processStub.records.isEmpty());
	}

	@Test
	public void createsInitialDesktopFile() throws Exception {
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE, new IOException("desktop file not existing"));

		registration.handleSchemes(Arrays.asList(ADT_SCHEME_INFO), Collections.emptyList());

		assertEquals(PATH_OWN_DESKTOP_FILE, fileProvider.writePath);

		assertAppNameInFileIs(PRODUCT_NAME);

		assertMimeTypeInFileIs("x-scheme-handler/adt;");

		assertExecInFileIs("/home/myuser/Eclipse/Eclipse %u");

		assertXdgMimeCalledFor("x-scheme-handler/adt");
	}

	@Test
	public void callsXdgMimeOnceForAllSchemes() throws Exception {
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE, getFileLines(OWN_EXECUTABLE_PATH, ""));

		registration.handleSchemes(Arrays.asList(ADT_SCHEME_INFO, OTHER_SCHEME_INFO), Collections.emptyList());

		assertFilePathIs(PATH_OWN_DESKTOP_FILE);

		assertMimeTypeInFileIs("x-scheme-handler/adt;x-scheme-handler/other;");

		assertXdgMimeCalledFor("x-scheme-handler/adt", "x-scheme-handler/other");
	}

	@Test
	public void returnsFallbackIfEclipseLauncherIsNotSet() throws Exception {
		System.clearProperty(ECLIPSE_LAUNCHER);
		String eclipseLauncher = registration.getEclipseLauncher();
		assertEquals("/home/myuser/Eclipse/" + "eclipse", eclipseLauncher);
	}

	@Test
	public void givesSchemeInfoForHandledScheme() throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE,
				getFileLines(OWN_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		processStub.result = OWN_DESKTOP_FILE; // this is returned by xdg-mime query default
		// x-scheme-handler/adt

		List<ISchemeInformation> registeredSchemes = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, registeredSchemes.size());
		assertEquals("adt", registeredSchemes.get(0).getName());
		assertTrue("Scheme should be handled", registeredSchemes.get(0).isHandled());
	}

	@Test
	public void givesSchemeInfoForSchemeHandledByOtherApp() throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OTHER_APP_DESKTOP_FILE,
				getFileLines(OTHER_APP_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		processStub.result = OTHER_APP_DESKTOP_FILE; // this is returned by xdg-mime query default
																// x-scheme-handler/adt

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals(OTHER_APP_EXECUTABLE_PATH, infos.get(0).getHandlerInstanceLocation());
	}

	@Test
	public void givesSchemeInfoForSchemeHandledByOtherAppAndInOwnDesktopFile() throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE,
				getFileLines(OWN_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		fileProvider.fileExistsAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OTHER_APP_DESKTOP_FILE,
				getFileLines(OTHER_APP_EXECUTABLE_PATH, "MimeType=x-scheme-handler/adt;"));

		processStub.result = OTHER_APP_DESKTOP_FILE; // this is returned by xdg-mime query default
		// x-scheme-handler/adt

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals(OTHER_APP_EXECUTABLE_PATH, infos.get(0).getHandlerInstanceLocation());
	}

	@Test
	public void givesSchemeInfoForSchemeNotHandledAnymoreButInXdgMimeForOtherApp() throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, true);
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE, getFileLines(OWN_EXECUTABLE_PATH, ""));
		fileProvider.readAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, getFileLines(OTHER_APP_EXECUTABLE_PATH, ""));

		processStub.result = OTHER_APP_DESKTOP_FILE;

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals("", infos.get(0).getHandlerInstanceLocation());
	}

	@Test
	public void givesSchemeInfoForSchemeNotHandledAnymoreDesktopFileNoLongerExistsButInXdgMimeForOtherApp()
			throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, false);
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, false);

		processStub.result = OTHER_APP_DESKTOP_FILE;

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals("", infos.get(0).getHandlerInstanceLocation());
	}

	@Test
	public void givesSchemeInfoForSchemeNotHandledAnymoreButInXdgMimeForOwn() throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, true);
		fileProvider.readAnswers.put(PATH_OWN_DESKTOP_FILE, getFileLines(OWN_EXECUTABLE_PATH, ""));
		fileProvider.readAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, getFileLines(OTHER_APP_EXECUTABLE_PATH, ""));

		processStub.result = OWN_DESKTOP_FILE;

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals("", infos.get(0).getHandlerInstanceLocation());
	}

	@Test
	public void givesSchemeInfoForSchemeNotHandledAnymoreDesktopFileNoLongerExistsButInXdgMimeForOwn()
			throws Exception {
		fileProvider.fileExistsAnswers.put(PATH_OWN_DESKTOP_FILE, false);
		fileProvider.fileExistsAnswers.put(PATH_OTHER_APP_DESKTOP_FILE, false);

		processStub.result = OWN_DESKTOP_FILE;

		List<ISchemeInformation> infos = registration.getSchemesInformation(Arrays.asList(ADT_SCHEME));

		assertEquals(1, infos.size());
		assertEquals("adt", infos.get(0).getName());
		assertFalse(infos.get(0).isHandled());
		assertEquals("", infos.get(0).getHandlerInstanceLocation());
	}

	private List<String> getFileLines(String exec, String mimeType) {
		return Arrays.asList("[Desktop Entry]", //
				"Exec=" + exec, //
				"NoDisplay=true", //
				mimeType, //
				"Type=Application");
	}

	private void assertFilePathIs(String filePath) {
		assertEquals(filePath, fileProvider.recordedReadPaths.get(0));
		assertEquals(filePath, fileProvider.writePath);
	}

	private void assertAppNameInFileIs(String name) {
		assertThat(new String(fileProvider.writtenBytes), new StringContains("Name=" + name));
	}

	private void assertMimeTypeInFileIs(String mimeType) {
		assertThat(new String(fileProvider.writtenBytes), new StringContains("MimeType=" + mimeType));
	}

	private void assertExecInFileIs(String exec) {
		assertThat(new String(fileProvider.writtenBytes), new StringContains("Exec=" + exec));
	}

	private void assertNoMimeTypeInFile() {
		assertThat(new String(fileProvider.writtenBytes),
				new IsNot<>(new StringContains("MimeType=x-scheme-handler/adt;")));
	}

	private void assertXdgMimeCalledFor(String... schemeHandler) {
		assertEquals(1, processStub.records.size());
		assertEquals("xdg-mime", processStub.records.get(0).process);
		String schemeHandlers = Arrays.stream(schemeHandler).collect(Collectors.joining(" "));
		assertArrayEquals(new String[] { "default", OWN_DESKTOP_FILE, schemeHandlers },
				processStub.records.get(0).args);
	}
}