/*******************************************************************************
 * Copyright (c) 2018 Red Hat Inc. and others.
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  Lucas Bullen (Red Hat Inc.) - initial implementation.
 *  Pierre-Yves B. <pyvesdev@gmail.com> - Bug 553376 - Logs preference page does not work on Windows
 *******************************************************************************/
package org.eclipse.lsp4e.ui;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.lsp4e.ContentTypeToLSPLaunchConfigEntry;
import org.eclipse.lsp4e.ContentTypeToLanguageServerDefinition;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.LoggingStreamConnectionProviderProxy;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.wizards.datatransfer.SmartImportWizard;

public class LoggingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

	private final class BooleanMapEditingSupport extends EditingSupport {

		private final Map<String, Boolean> map;

		private BooleanMapEditingSupport(TableViewer viewer,  Map<String, Boolean> map) {
			super(viewer);
			this.map = map;
		}

		@Override
		protected void setValue(Object element, Object value) {
			ContentTypeToLanguageServerDefinition server = (ContentTypeToLanguageServerDefinition)element;
			map.put(server.getValue().id, (Boolean)value);
			hasLoggingBeenChanged = true;
			getViewer().refresh(element);
		}

		@Override
		protected Object getValue(Object element) {
			ContentTypeToLanguageServerDefinition server = (ContentTypeToLanguageServerDefinition)element;
			return map.get(server.getValue().id);
		}

		@Override
		protected CellEditor getCellEditor(Object element) {
			return new CheckboxCellEditor();
		}

		@Override
		protected boolean canEdit(Object element) {
			return true;
		}
	}

	private final class BooleanMapLabelProvider extends ColumnLabelProvider {
		private final Map<String, Boolean> map;

		private BooleanMapLabelProvider(Map<String, Boolean> map) {
			super();
			this.map = map;
		}

		@Override
		public String getText(Object element) {
			return map.getOrDefault(((ContentTypeToLanguageServerDefinition) element).getValue().id, false).booleanValue()
							? Messages.PreferencePage_enablementCondition_true
							: Messages.PreferencePage_enablementCondition_false;
		}
	}

	private TableViewer languageServerViewer;
	private TableViewer launchConfigurationViewer;
	private Map<String, Boolean> serverEnableLoggingToFile = new HashMap<>();
	private Map<String, Boolean> serverEnableLoggingToConsole = new HashMap<>();
	private IPreferenceStore store = LanguageServerPlugin.getDefault().getPreferenceStore();
	private boolean hasLoggingBeenChanged = false;

	@Override
	public void init(IWorkbench workbench) {
		//nothing to do
	}

	@Override
	protected Control createContents(Composite parent) {
		Composite res = new Composite(parent, SWT.NONE);
		res.setLayout(new GridLayout(1, false));

		createStaticServersTable(res);
		createLaunchConfigurationServersTable(res);
		createLoggingContents(res);
		updateInputs();
		return res;
	}

	private void createStaticServersTable(Composite res) {
		languageServerViewer = new TableViewer(res, SWT.FULL_SELECTION);
		languageServerViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		languageServerViewer.setContentProvider(new ArrayContentProvider());

		TableViewerColumn launchConfigColumn = new TableViewerColumn(languageServerViewer, SWT.NONE);
		launchConfigColumn.getColumn().setText(Messages.PreferencesPage_languageServer);
		launchConfigColumn.getColumn().setWidth(300);
		launchConfigColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return ((ContentTypeToLanguageServerDefinition) element).getValue().label;
			}
		});
		addLoggingColumnsToViewer(languageServerViewer);
		languageServerViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		languageServerViewer.getTable().setHeaderVisible(true);
		languageServerViewer.getTable().setLinesVisible(true);
	}

	private void createLaunchConfigurationServersTable(Composite res) {
		launchConfigurationViewer = new TableViewer(res, SWT.FULL_SELECTION);
		launchConfigurationViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		launchConfigurationViewer.setContentProvider(new ArrayContentProvider());

		TableViewerColumn launchConfigColumn = new TableViewerColumn(launchConfigurationViewer, SWT.NONE);
		launchConfigColumn.getColumn().setText(Messages.PreferencesPage_LaunchConfiguration);
		launchConfigColumn.getColumn().setWidth(300);
		launchConfigColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return ((ContentTypeToLSPLaunchConfigEntry) element).getLaunchConfiguration().getName();
			}
		});
		addLoggingColumnsToViewer(launchConfigurationViewer);
		launchConfigurationViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		launchConfigurationViewer.getTable().setHeaderVisible(true);
		languageServerViewer.getTable().setLinesVisible(true);
	}

	private void addLoggingColumnsToViewer(TableViewer viewer) {
		TableViewerColumn logToFileColumn = new TableViewerColumn(viewer, SWT.NONE);
		logToFileColumn.getColumn().setText(Messages.PreferencesPage_logging_toFile_title);
		logToFileColumn.getColumn().setWidth(100);
		logToFileColumn.setLabelProvider(new BooleanMapLabelProvider(serverEnableLoggingToFile));
		logToFileColumn.setEditingSupport(new BooleanMapEditingSupport(viewer, serverEnableLoggingToFile));

		TableViewerColumn logToConsoleColumn = new TableViewerColumn(viewer, SWT.NONE);
		logToConsoleColumn.getColumn().setText(Messages.PreferencesPage_logging_toConsole_title);
		logToConsoleColumn.getColumn().setWidth(125);
		logToConsoleColumn.setLabelProvider(new BooleanMapLabelProvider(serverEnableLoggingToConsole));
		logToConsoleColumn.setEditingSupport(new BooleanMapEditingSupport(viewer, serverEnableLoggingToConsole));
	}

	private void createLoggingContents(Composite res) {
		Composite loggingComposite = new Composite(res, SWT.NONE);
		loggingComposite.setLayout(new GridLayout(3, false));
		loggingComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));

		Label infoLabel = new Label(loggingComposite, SWT.NONE);
		infoLabel.setText(Messages.preferencesPage_logging_info);
		infoLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
		Link logFolderLabel = new Link(loggingComposite, SWT.NONE);
		logFolderLabel.setText(NLS.bind(Messages.preferencesPage_logging_fileLogsLocation, LoggingStreamConnectionProviderProxy.getLogDirectory()));
		logFolderLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
		logFolderLabel.addSelectionListener(widgetSelectedAdapter(e -> {
			SmartImportWizard importWizard = new SmartImportWizard();
			importWizard.setInitialImportSource(LoggingStreamConnectionProviderProxy.getLogDirectory());
			WizardDialog dialog = new WizardDialog(logFolderLabel.getShell(), importWizard);
			dialog.open();
		}));
		Label fileLoggingLabel = new Label(loggingComposite, SWT.NONE);
		fileLoggingLabel.setText(Messages.PreferencesPage_logging_toFile_description);
		Button disableFileLogging = new Button(loggingComposite, SWT.NONE);
		disableFileLogging.setText(Messages.PreferencePage_enablementCondition_disableAll);
		disableFileLogging.addSelectionListener(widgetSelectedAdapter(e -> {
			serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s, false));
			hasLoggingBeenChanged = true;
			languageServerViewer.refresh();
			launchConfigurationViewer.refresh();
		}));
		Button enableFileLogging = new Button(loggingComposite, SWT.NONE);
		enableFileLogging.setText(Messages.PreferencePage_enablementCondition_enableAll);
		enableFileLogging.addSelectionListener(widgetSelectedAdapter(e -> {
			serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s, true));
			hasLoggingBeenChanged = true;
			languageServerViewer.refresh();
			launchConfigurationViewer.refresh();
		}));

		Label consoleLoggingLabel = new Label(loggingComposite, SWT.NONE);
		consoleLoggingLabel.setText(Messages.PreferencesPage_logging_toConsole_description);
		Button disableConsoleLogging = new Button(loggingComposite, SWT.NONE);
		disableConsoleLogging.setText(Messages.PreferencePage_enablementCondition_disableAll);
		disableConsoleLogging.addSelectionListener(widgetSelectedAdapter(e -> {
			serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s, false));
			hasLoggingBeenChanged = true;
			languageServerViewer.refresh();
			launchConfigurationViewer.refresh();
		}));
		Button enableConsoleLogging = new Button(loggingComposite, SWT.NONE);
		enableConsoleLogging.setText(Messages.PreferencePage_enablementCondition_enableAll);
		enableConsoleLogging.addSelectionListener(widgetSelectedAdapter(e -> {
			serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s, true));
			hasLoggingBeenChanged = true;
			languageServerViewer.refresh();
			launchConfigurationViewer.refresh();
		}));
	}

	@Override
	protected void performDefaults() {
		serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s,
				store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(s))));
		serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s,
				store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(s))));
		launchConfigurationViewer.refresh();
		languageServerViewer.refresh();
		super.performDefaults();
	}

	private void applyLoggingEnablment() {
		serverEnableLoggingToFile.forEach((s, b) -> store.setValue(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(s), b));
		serverEnableLoggingToConsole.forEach((s, b) -> store.setValue(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(s), b));
		hasLoggingBeenChanged = false;
	}

	@Override
	public boolean performOk() {
		if (hasLoggingBeenChanged) {
			applyLoggingEnablment();
			MessageDialog dialog = new MessageDialog(getShell(), Messages.PreferencesPage_restartWarning_title, null,
					Messages.PreferencesPage_restartWarning_message, MessageDialog.WARNING,
					new String[] { IDialogConstants.NO_LABEL, Messages.PreferencesPage_restartWarning_restart }, 1);
			if (dialog.open() == 1) {
				PlatformUI.getWorkbench().restart();
			}
		}
		return super.performOk();
	}

	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		updateInputs();
	}

	private void updateInputs() {
		Set<String> languageServerIDs = new HashSet<>();
		List<ContentTypeToLSPLaunchConfigEntry> contentTypeToLSPLaunchConfigEntries = new ArrayList<>();
		LanguageServersRegistry.getInstance().getContentTypeToLSPLaunches().forEach(o -> {
			String id = o.getValue().id;
			if (languageServerIDs.add(id)) {
				contentTypeToLSPLaunchConfigEntries.add(o);
				serverEnableLoggingToFile.put(id, serverEnableLoggingToFile.getOrDefault(id,
						store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(id))));
				serverEnableLoggingToConsole.put(id, serverEnableLoggingToConsole.getOrDefault(id,
						store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(id))));
			}
		});

		launchConfigurationViewer.setInput(contentTypeToLSPLaunchConfigEntries);
		launchConfigurationViewer.refresh();

		languageServerIDs.clear();
		List<ContentTypeToLanguageServerDefinition> contentTypeToLanguageServerDefinitions = new ArrayList<>();
		LanguageServersRegistry.getInstance().getContentTypeToLSPExtensions().forEach(o -> {
			String id = o.getValue().id;
			if (languageServerIDs.add(id)) {
				contentTypeToLanguageServerDefinitions.add(o);
				serverEnableLoggingToFile.put(id, serverEnableLoggingToFile.getOrDefault(id,
						store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(id))));
				serverEnableLoggingToConsole.put(id, serverEnableLoggingToConsole.getOrDefault(id,
						store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(id))));
			}
		});

		languageServerViewer.setInput(contentTypeToLanguageServerDefinitions);
		launchConfigurationViewer.refresh();
	}
}
