/*=============================================================================#
 # Copyright (c) 2007, 2019 Stephan Wahlbrink 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, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImIdentityList;

import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;


/**
 * Reconciler for {@link ISourceEditor}s using Eclipse Job API.
 */
public class EcoReconciler2 implements IReconciler {
	
	
	public static interface ISourceUnitStrategy {
		
		void setInput(ISourceUnit su);
		
	}
	
	protected static class StrategyEntry {
		
		final IReconcilingStrategy strategy;
		final IReconcilingStrategyExtension strategyExtension;
		final ISourceUnitStrategy suStrategy;
		boolean initialed;
		
		StrategyEntry(final IReconcilingStrategy strategy) {
			this.strategy= strategy;
			this.strategyExtension= (strategy instanceof IReconcilingStrategyExtension) ?
					(IReconcilingStrategyExtension) strategy : null;
			this.initialed= false;
			this.suStrategy= (strategy instanceof ISourceUnitStrategy) ?
					(ISourceUnitStrategy) strategy : null;
		}
		
		@Override
		public int hashCode() {
			return this.strategy.hashCode();
		}
		
		@Override
		public boolean equals(final Object obj) {
			if (obj instanceof StrategyEntry) {
				return ( ((StrategyEntry) obj).strategy == this.strategy);
			}
			return false;
		}
	}
	
	
	private class ReconcileJob extends Job implements ISchedulingRule {
		
		ReconcileJob(final String name) {
			super("Reconciler '"+name+"'"); //$NON-NLS-1$ //$NON-NLS-2$
			setPriority(Job.SHORT);
			setRule(this);
			setSystem(true);
			setUser(false);
		}
		
		@Override
		protected IStatus run(final IProgressMonitor monitor) {
			if (!monitor.isCanceled()) {
				processReconcile(monitor);
			}
			return Status.OK_STATUS;
		}
		
		@Override
		public boolean contains(final ISchedulingRule rule) {
			return rule == this;
		}
		
		@Override
		public boolean isConflicting(final ISchedulingRule rule) {
			return rule == this;
		}
	}
	
	
	private class VisibleListener implements Listener {
		@Override
		public void handleEvent(final Event event) {
			switch (event.type) {
			case SWT.Show:
				EcoReconciler2.this.isEditorVisible= true;
				return;
			case SWT.Hide:
				EcoReconciler2.this.isEditorVisible= false;
				return;
			}
		}
	}
	
	/**
	 * Internal document listener and text input listener.
	 */
	private class DocumentListener implements IDocumentListener, ITextInputListener {
		
		@Override
		public void documentAboutToBeChanged(final DocumentEvent e) {
		}
		
		@Override
		public void documentChanged(final DocumentEvent e) {
			scheduleReconcile();
		}
		
		@Override
		public void inputDocumentAboutToBeChanged(final IDocument oldInput, final IDocument newInput) {
			if (EcoReconciler2.this.document != null && oldInput == EcoReconciler2.this.document && newInput != EcoReconciler2.this.document) {
				disconnectDocument();
			}
		}
		
		@Override
		public void inputDocumentChanged(final IDocument oldInput, final IDocument newInput) {
			connectDocument();
		}
	}
	
	/** Internal document and text input listener. */
	private final DocumentListener documentListener= new DocumentListener();
	private VisibleListener visibleListener;
	/** Job for scheduled background reconciling */
	private ReconcileJob job;
	/** The background thread delay. */
	private int delay= 500;
	
	/** The text viewer's document. */
	private IDocument document;
	/** The text viewer */
	private ITextViewer viewer;
	/** optional editor */
	private ISourceEditor editor;
	
	/** Tells whether this reconciler's editor is active. */
	private volatile boolean isEditorVisible;
	
	/** The current source unit */
	private ISourceUnit sourceUnit;
	
	private final CopyOnWriteIdentityListSet<StrategyEntry> strategies= new CopyOnWriteIdentityListSet<>();
	
	
	/**
	 * Creates a new reconciler without configuring it.
	 */
	public EcoReconciler2() {
		super();
	}
	
	/**
	 * Creates a new reconciler without configuring it.
	 */
	public EcoReconciler2(final ISourceEditor editor) {
		super();
		this.editor= editor;
	}
	
	
	/**
	 * Tells the reconciler how long it should wait for further text changes before
	 * activating the appropriate reconciling strategies.
	 * 
	 * @param delay the duration in milliseconds of a change collection period.
	 */
	public void setDelay(final int delay) {
		this.delay= delay;
	}
	
	/**
	 * Returns the input document of the text viewer this reconciler is installed on.
	 * 
	 * @return the reconciler document
	 */
	protected IDocument getDocument() {
		return this.document;
	}
	
	
	/**
	 * Returns the text viewer this reconciler is installed on.
	 * 
	 * @return the text viewer this reconciler is installed on
	 */
	protected ITextViewer getTextViewer() {
		return this.viewer;
	}
	
	/**
	 * Tells whether this reconciler's editor is active.
	 * 
	 * @return <code>true</code> if the editor is active
	 */
	protected boolean isEditorVisible() {
		return this.isEditorVisible;
	}
	
	
	@Override
	public void install(final ITextViewer textViewer) {
		Assert.isNotNull(textViewer);
		this.viewer= textViewer;
		
		this.visibleListener= new VisibleListener();
		final StyledText textWidget= this.viewer.getTextWidget();
		textWidget.addListener(SWT.Show, this.visibleListener);
		textWidget.addListener(SWT.Hide, this.visibleListener);
		this.isEditorVisible= textWidget.isVisible();
		
		this.viewer.addTextInputListener(this.documentListener);
		connectDocument();
	}
	
	@Override
	public void uninstall() {
		if (this.viewer != null) {
			disconnectDocument();
			this.viewer.removeTextInputListener(this.documentListener);
			this.viewer= null;
		}
	}
	
	protected void connectDocument() {
		final IDocument document= this.viewer.getDocument();
		if (document == null || this.document == document) {
			return;
		}
		this.document= document;
		this.sourceUnit= this.editor.getSourceUnit();
		reconcilerDocumentChanged(this.document);
		
		this.job= new ReconcileJob(getInputName());
		this.document.addDocumentListener(this.documentListener);
		
		scheduleReconcile();
	}
	
	protected String getInputName() {
		if (this.sourceUnit != null) {
			return this.sourceUnit.getId();
		}
		return "-"; //$NON-NLS-1$
	}
	
	/**
	 * Hook called when the document whose contents should be reconciled
	 * has been changed, i.e., the input document of the text viewer this
	 * reconciler is installed on. Usually, subclasses use this hook to
	 * inform all their reconciling strategies about the change.
	 * 
	 * @param newDocument the new reconciler document
	 */
	protected void reconcilerDocumentChanged(final IDocument newDocument) {
	}
	
	protected void disconnectDocument() {
		if (this.document != null) {
			this.document.removeDocumentListener(this.documentListener);
			this.document= null;
			this.sourceUnit= null;
		}
		if (this.job != null) {
			this.job.cancel();
			this.job= null;
		}
	}
	
	private synchronized void scheduleReconcile() {
		if ((this.job.getState() & (Job.SLEEPING | Job.WAITING)) == 0) {
			aboutToBeReconciled();
		}
		this.job.cancel();
		this.job.schedule(this.delay);
	}
	
	/**
	 * Hook for subclasses which want to perform some
	 * action as soon as reconciliation is needed.
	 * <p>
	 * Default implementation is to do nothing.
	 */
	protected void aboutToBeReconciled() {
	}
	
	protected void processReconcile(final IProgressMonitor monitor) {
		final IDocument document= getDocument();
		final ISourceUnit input= this.sourceUnit;
		if (document == null || input == null) {
			return;
		}
		final IRegion region= new Region(0, document.getLength());
		final ImIdentityList<StrategyEntry> reconcilingStrategies= getReconcilingStrategies();
		for (final StrategyEntry s : reconcilingStrategies) {
			synchronized (s.strategy) {
				if (s.suStrategy != null && input != null) {
					s.suStrategy.setInput(input);
				}
				else {
					s.strategy.setDocument(document);
				}
				if (!prepareStrategyReconcile(s)) {
					continue;
				}
				if (monitor.isCanceled()) {
					return;
				}
				if (s.strategyExtension != null) {
					s.strategyExtension.setProgressMonitor(monitor);
					if (!s.initialed) {
						s.strategyExtension.initialReconcile();
						s.initialed= true;
						continue;
					}
				}
				s.strategy.reconcile(region);
			}
		}
	}
	
	protected boolean prepareStrategyReconcile(final StrategyEntry s) {
		return true;
	}
	
	public void addReconcilingStrategy(final IReconcilingStrategy strategy) {
		this.strategies.add(new StrategyEntry(strategy));
	}
	
	protected ImIdentityList<StrategyEntry> getReconcilingStrategies() {
		return this.strategies.toList();
	}
	
	@Override
	public IReconcilingStrategy getReconcilingStrategy(final String contentType) {
		return null;
	}
	
}
