/*******************************************************************************
 *  Copyright (c) 2005, 2017 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     QNX Software System
 *     Anton Leherbauer (Wind River Systems)
 *     Sergey Prigogin (Google)
 *     Marc-Andre Laperle (Ericsson) - Mostly copied from CSourceViewerConfiguration
 *     Nathan Ridge
 *     Manish Khurana
 *******************************************************************************/

package org.eclipse.lsp4e.cpp.language;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.model.ICLanguageKeywords;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.internal.ui.editor.CEditor.BracketInserter;
import org.eclipse.cdt.internal.ui.text.CCodeScanner;
import org.eclipse.cdt.internal.ui.text.CCommentScanner;
import org.eclipse.cdt.internal.ui.text.CPreprocessorScanner;
import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
import org.eclipse.cdt.internal.ui.text.PartitionDamager;
import org.eclipse.cdt.internal.ui.text.SingleTokenCScanner;
import org.eclipse.cdt.internal.ui.text.TokenStore;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.ILanguageUI;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.text.AbstractCScanner;
import org.eclipse.cdt.ui.text.ICColorConstants;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.ui.text.ICTokenScanner;
import org.eclipse.cdt.ui.text.ITokenStore;
import org.eclipse.cdt.ui.text.ITokenStoreFactory;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights;
import org.eclipse.lsp4e.cpp.language.cquery.HighlightSymbol;
import org.eclipse.lsp4j.Range;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.TextEditor;

/**
 * Hack-ish reconciler to get some colors in the generic editor using the C/C++
 * Server.
 */
@SuppressWarnings("restriction")
public class PresentationReconcilerCPP extends CPresentationReconciler {

	private CCommentScanner fSinglelineCommentScanner;
	private CCommentScanner fMultilineCommentScanner;
	private SingleTokenCScanner fStringScanner;
	private AbstractCScanner fCodeScanner;
	private CqueryLineBackgroundListener fLineBackgroundListener = new CqueryLineBackgroundListener();
	private ITextViewer textViewer;
	private TextInputListenerCPP textInputListener;
	private BracketInserter fBracketInserter;

	public static Set<PresentationReconcilerCPP> presentationReconcilers = ConcurrentHashMap.newKeySet();

	protected ITokenStoreFactory getTokenStoreFactory() {
		return new ITokenStoreFactory() {
			@Override
			public ITokenStore createTokenStore(String[] propertyColorNames) {
				return new TokenStore(CUIPlugin.getDefault().getTextTools().getColorManager(), CUIPlugin.getDefault().getCombinedPreferenceStore(), propertyColorNames);
			}
		};
	}

	protected ILanguage getLanguage() {
		// fallback
		return GPPLanguage.getDefault();
	}

	protected RuleBasedScanner getCodeScanner(ILanguage language) {
		if (fCodeScanner != null) {
			return fCodeScanner;
		}
		RuleBasedScanner scanner= null;

		if (language != null) {
			ICLanguageKeywords keywords = language.getAdapter(ICLanguageKeywords.class);
			if (keywords != null) {
				scanner = new CCodeScanner(getTokenStoreFactory(), keywords);
			} else {
				ILanguageUI languageUI = language.getAdapter(ILanguageUI.class);
				if (languageUI != null) {
					scanner = languageUI.getCodeScanner();
				}
			}
		}

		if (scanner == null) {
			scanner = new CCodeScanner(getTokenStoreFactory(), GPPLanguage.getDefault());
		}
		if (scanner instanceof AbstractCScanner) {
			fCodeScanner= (AbstractCScanner)scanner;
		}
		return scanner;
	}

	public PresentationReconcilerCPP() {
		fStringScanner= new SingleTokenCScanner(getTokenStoreFactory(), ICColorConstants.C_STRING);
		fMultilineCommentScanner= new CCommentScanner(getTokenStoreFactory(),  ICColorConstants.C_MULTI_LINE_COMMENT);
		fSinglelineCommentScanner= new CCommentScanner(getTokenStoreFactory(),  ICColorConstants.C_SINGLE_LINE_COMMENT);

		setDocumentPartitioning(CUIPlugin.getDefault().getTextTools().getDocumentPartitioning());

		ILanguage language= getLanguage();
		RuleBasedScanner scanner = getCodeScanner(language);

		DefaultDamagerRepairer dr= new DefaultDamagerRepairer(scanner);

		setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
		setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

		dr= new DefaultDamagerRepairer(fSinglelineCommentScanner);
		setDamager(dr, ICPartitions.C_SINGLE_LINE_COMMENT);
		setRepairer(dr, ICPartitions.C_SINGLE_LINE_COMMENT);

		dr= new DefaultDamagerRepairer(fMultilineCommentScanner);
		setDamager(dr, ICPartitions.C_MULTI_LINE_COMMENT);
		setRepairer(dr, ICPartitions.C_MULTI_LINE_COMMENT);

		ICTokenScanner docCommentSingleScanner= getSinglelineDocCommentScanner(null);
		if (docCommentSingleScanner!=null) {
			dr= new DefaultDamagerRepairer(docCommentSingleScanner);
			setDamager(dr, ICPartitions.C_SINGLE_LINE_DOC_COMMENT);
			setRepairer(dr, ICPartitions.C_SINGLE_LINE_DOC_COMMENT);
		}

		ICTokenScanner docCommentMultiScanner= getMultilineDocCommentScanner(null);
		if (docCommentMultiScanner!=null) {
			dr= new DefaultDamagerRepairer(docCommentMultiScanner);
			setDamager(dr, ICPartitions.C_MULTI_LINE_DOC_COMMENT);
			setRepairer(dr, ICPartitions.C_MULTI_LINE_DOC_COMMENT);
		}

		dr= new DefaultDamagerRepairer(fStringScanner);
		setDamager(dr, ICPartitions.C_STRING);
		setRepairer(dr, ICPartitions.C_STRING);

		dr= new DefaultDamagerRepairer(fStringScanner);
		setDamager(dr, ICPartitions.C_CHARACTER);
		setRepairer(dr, ICPartitions.C_CHARACTER);

		dr= new DefaultDamagerRepairer(getPreprocessorScanner(language));
		setDamager(new PartitionDamager(), ICPartitions.C_PREPROCESSOR);
		setRepairer(dr, ICPartitions.C_PREPROCESSOR);
	}

	@Override
	protected TextPresentation createPresentation(IRegion damage, IDocument document) {
		TextPresentation presentation = super.createPresentation(damage, document);

		IDocument doc = textViewer.getDocument();
		URI uri = Server2ClientProtocolExtension.getUri(doc);

		if (uri == null) {
			return presentation;
		}

		List<HighlightSymbol> semanticHighlights = CquerySemanticHighlights.uriToSemanticHighlightsMapping.get(uri);

		if(semanticHighlights == null) {
			return presentation;
		}

		IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore();
		List<StyleRange> styleRanges = new ArrayList<>();

		for (HighlightSymbol highlight : semanticHighlights) {

			String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(), highlight.getParentKind(), highlight.getStorage());
			String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
								+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;

			boolean isBold = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
								+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX);
			boolean isItalic = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
								+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX);
			boolean isUnderline = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
								+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX);
			boolean isStrikethrough = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
								+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX);

			Color color = new Color(Display.getCurrent(),
									PreferenceConverter.getColor(CUIPlugin.getDefault().getPreferenceStore(), colorKey));

			int damageStartOffset = damage.getOffset();
			int damageEndOffset = damageStartOffset + damage.getLength();

			List<Range> ranges = highlight.getRanges();
			for (Range range : ranges) {

				int offset = 0, length = 0;
				try {
					offset = doc.getLineOffset(range.getStart().getLine()) + range.getStart().getCharacter();
					length = doc.getLineOffset(range.getEnd().getLine()) + range.getEnd().getCharacter() - offset;
				} catch (BadLocationException e) {
					Activator.log(e);
				}
				if ((offset + length) >= damageStartOffset && offset < damageEndOffset) {

					StyleRange styleRange = new StyleRange(offset, length, color, null);

					if (isBold) {
						styleRange.fontStyle = SWT.BOLD;
					}
					if (isItalic) {
						styleRange.fontStyle |= SWT.ITALIC;
					}
					if (isUnderline) {
						styleRange.underline = true;
					}
					if (isStrikethrough) {
						styleRange.strikeout = true;
					}

					styleRanges.add(styleRange);
				}
			}
		}

		StyleRange[] styleRangesArray = new StyleRange[styleRanges.size()];
		styleRangesArray = styleRanges.toArray(styleRangesArray);
		presentation.replaceStyleRanges(styleRangesArray);
		return presentation;
	}

	/**
	 * Returns the C multi-line doc comment scanner for this configuration.
	 *
	 * @return the C multi-line doc comment scanner
	 */
	protected ICTokenScanner getMultilineDocCommentScanner(IResource resource) {
		if (fMultilineDocCommentScanner == null) {
			if (resource == null) {
				resource= ResourcesPlugin.getWorkspace().getRoot();
			}
//			IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getMultilineConfiguration();
//			fMultilineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory());
			if (fMultilineDocCommentScanner == null) {
				// fallback: normal comment highlighting
				fMultilineDocCommentScanner= fMultilineCommentScanner;
			}
		}
		return fMultilineDocCommentScanner;
	}

	protected ICTokenScanner fMultilineDocCommentScanner;
	/**
	 * The C single-line doc comment scanner.
	 */
	protected ICTokenScanner fSinglelineDocCommentScanner;

	protected ICTokenScanner getSinglelineDocCommentScanner(IResource resource) {
		if (fSinglelineDocCommentScanner == null) {
			if (resource == null) {
				resource= ResourcesPlugin.getWorkspace().getRoot();
			}
//			IDocCommentViewerConfiguration owner= DocCommentOwnerManager.getInstance().getCommentOwner(resource).getSinglelineConfiguration();
//			fSinglelineDocCommentScanner= owner.createCommentScanner(getTokenStoreFactory());
			if (fSinglelineDocCommentScanner == null) {
				// fallback: normal comment highlighting
				fSinglelineDocCommentScanner= fSinglelineCommentScanner;
			}
		}
		return fSinglelineDocCommentScanner;
	}

	protected AbstractCScanner fPreprocessorScanner;

	protected RuleBasedScanner getPreprocessorScanner(ILanguage language) {
		if (fPreprocessorScanner != null) {
			return fPreprocessorScanner;
		}
		AbstractCScanner scanner= null;
		ICLanguageKeywords keywords = language == null ? null : (ICLanguageKeywords) language.getAdapter(ICLanguageKeywords.class);
		if (keywords != null) {
			scanner = new CPreprocessorScanner(getTokenStoreFactory(), keywords);
		}
		if (scanner == null) {
			keywords = GPPLanguage.getDefault().getAdapter(ICLanguageKeywords.class);
			scanner= new CPreprocessorScanner(getTokenStoreFactory(), keywords);
		}
		fPreprocessorScanner= scanner;
		return fPreprocessorScanner;
	}

	public class TextInputListenerCPP implements ITextInputListener {

		@Override
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			setupDocument(newInput);
		}

		@Override
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		}
	}

	public void setupDocument(IDocument newDocument) {
		if (newDocument != null) {
			fLineBackgroundListener.setCurrentDocument(newDocument);
		}
	}

	public ITextViewer getTextViewer() {
		return textViewer;
	}

	@Override
	public void install(ITextViewer viewer) {
		super.install(viewer);
		this.textViewer = viewer;
		textInputListener = new TextInputListenerCPP();
		viewer.addTextInputListener(textInputListener);
		IDocument document= viewer.getDocument();
		if (document != null) {
		    textInputListener.inputDocumentChanged(null, document);
		}
		StyledText textWidget = textViewer.getTextWidget();
		textWidget.addLineBackgroundListener(fLineBackgroundListener);
		presentationReconcilers.add(this);

//		Using asyncExec() to make sure that by the time Runnable runs,
//		the Editor is active and we don't get a NPE.
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
//				To provide bracket auto-completion support of CEditor in Generic Editor of LSP4E-CPP

				TextEditor editor = (TextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
				fBracketInserter = new BracketInserter(editor, true);
				fBracketInserter.setSourceViewer((SourceViewer) textViewer);
				((TextViewer) textViewer).prependVerifyKeyListener(fBracketInserter);
			}});
	}

	@Override
	public void uninstall() {
		super.uninstall();
		textViewer.getTextWidget().removeLineBackgroundListener(fLineBackgroundListener);
		textViewer.removeTextInputListener(textInputListener);
		((TextViewer) textViewer).removeVerifyKeyListener(fBracketInserter);
		presentationReconcilers.remove(this);
	}
}
