/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Andrey Loskutov <loskutov@gmx.de> - bug 489546
 *******************************************************************************/
package org.eclipse.ui.internal.console;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.PatternSyntaxException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleListener;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsolePageParticipant;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.IPatternMatchListener;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * The singleton console manager.
 *
 * @since 3.0
 */
public class ConsoleManager implements IConsoleManager {

	/**
	 * Console listeners
	 */
	private ListenerList<IConsoleListener> fListeners = null;

	/**
	 * List of registered consoles
	 */
	private List<IConsole> fConsoles = new ArrayList<IConsole>(10);


	// change notification constants
	private final static int ADDED = 1;
	private final static int REMOVED = 2;

	private List<PatternMatchListenerExtension> fPatternMatchListeners;

	private List<ConsolePageParticipantExtension> fPageParticipants;

	private List<ConsoleFactoryExtension> fConsoleFactoryExtensions;

	private List<IConsoleView> fConsoleViews = new ArrayList<IConsoleView>();

    private boolean fWarnQueued = false;

    private RepaintJob fRepaintJob = new RepaintJob();

    private class RepaintJob extends WorkbenchJob {
		private Set<IConsole> list = new HashSet<IConsole>();

        public RepaintJob() {
            super("schedule redraw() of viewers"); //$NON-NLS-1$
            setSystem(true);
        }

        void addConsole(IConsole console) {
        	synchronized (list) {
        		list.add(console);
			}
        }

        @Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
            synchronized (list) {
                if (list.isEmpty()) {
                    return Status.OK_STATUS;
                }

                IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows();
                for (int i = 0; i < workbenchWindows.length; i++) {
                    IWorkbenchWindow window = workbenchWindows[i];
                    if (window != null) {
                        IWorkbenchPage page = window.getActivePage();
                        if (page != null) {
                            IViewPart part = page.findView(IConsoleConstants.ID_CONSOLE_VIEW);
                            if (part != null && part instanceof IConsoleView) {
                                ConsoleView view = (ConsoleView) part;
                                if (list.contains(view.getConsole())) {
                                    Control control = view.getCurrentPage().getControl();
                                    if (!control.isDisposed()) {
                                        control.redraw();
                                    }
                                }
                            }

                        }
                    }
                }
                list.clear();
            }
            return Status.OK_STATUS;
        }
    }

	/**
	 * Notifies a console listener of additions or removals
	 */
	class ConsoleNotifier implements ISafeRunnable {

		private IConsoleListener fListener;
		private int fType;
		private IConsole[] fChanged;

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, ConsolePlugin.getUniqueIdentifier(), IConsoleConstants.INTERNAL_ERROR, ConsoleMessages.ConsoleManager_0, exception);
			ConsolePlugin.log(status);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			switch (fType) {
				case ADDED:
					fListener.consolesAdded(fChanged);
					break;
				case REMOVED:
					fListener.consolesRemoved(fChanged);
					break;
				default:
					break;
			}
		}

		/**
		 * Notifies the given listener of the adds/removes
		 *
		 * @param consoles the consoles that changed
		 * @param update the type of change
		 */
		public void notify(IConsole[] consoles, int update) {
			if (fListeners == null) {
				return;
			}
			fChanged = consoles;
			fType = update;
			for (IConsoleListener iConsoleListener : fListeners) {
				fListener = iConsoleListener;
                SafeRunner.run(this);
			}
			fChanged = null;
			fListener = null;
		}
	}

	public void registerConsoleView(ConsoleView view) {
	    synchronized (fConsoleViews) {
	        fConsoleViews.add(view);
	    }
	}
    public void unregisterConsoleView(ConsoleView view) {
        synchronized (fConsoleViews) {
            fConsoleViews.remove(view);
        }
    }

    /* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#addConsoleListener(org.eclipse.ui.console.IConsoleListener)
	 */
	@Override
	public void addConsoleListener(IConsoleListener listener) {
		if (fListeners == null) {
			fListeners = new ListenerList<>();
		}
		fListeners.add(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#removeConsoleListener(org.eclipse.ui.console.IConsoleListener)
	 */
	@Override
	public void removeConsoleListener(IConsoleListener listener) {
		if (fListeners != null) {
			fListeners.remove(listener);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#addConsoles(org.eclipse.ui.console.IConsole[])
	 */
	@Override
	public void addConsoles(IConsole[] consoles) {
		List<IConsole> added = new ArrayList<IConsole>(consoles.length);
		synchronized (fConsoles) {
			for (int i = 0; i < consoles.length; i++) {
			    IConsole console = consoles[i];
			    if(console instanceof TextConsole) {
			        TextConsole ioconsole = (TextConsole)console;
			        createPatternMatchListeners(ioconsole);
			    }
				if (!fConsoles.contains(console)) {
					fConsoles.add(console);
					added.add(console);
				}
			}
		}
		if (!added.isEmpty()) {
			fireUpdate(added.toArray(new IConsole[added.size()]), ADDED);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#removeConsoles(org.eclipse.ui.console.IConsole[])
	 */
	@Override
	public void removeConsoles(IConsole[] consoles) {
		List<IConsole> removed = new ArrayList<IConsole>(consoles.length);
		synchronized (fConsoles) {
			for (int i = 0; i < consoles.length; i++) {
				IConsole console = consoles[i];
				if (fConsoles.remove(console)) {
					removed.add(console);
				}
			}
		}
		if (!removed.isEmpty()) {
			fireUpdate(removed.toArray(new IConsole[removed.size()]), REMOVED);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#getConsoles()
	 */
	@Override
	public IConsole[] getConsoles() {
		synchronized (fConsoles) {
			return fConsoles.toArray(new IConsole[fConsoles.size()]);
		}
	}

	/**
	 * Fires notification.
	 *
	 * @param consoles consoles added/removed
	 * @param type ADD or REMOVE
	 */
	private void fireUpdate(IConsole[] consoles, int type) {
		new ConsoleNotifier().notify(consoles, type);
	}


	private class ShowConsoleViewJob extends WorkbenchJob {
		private Set<IConsole> queue = new LinkedHashSet<IConsole>();

		ShowConsoleViewJob() {
			super("Show Console View"); //$NON-NLS-1$
			setSystem(true);
			setPriority(Job.SHORT);
		}

		void addConsole(IConsole console) {
			synchronized (queue) {
				queue.add(console);
			}
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			Set<IConsole> consolesToShow;
			synchronized (queue) {
				consolesToShow = new LinkedHashSet<>(queue);
				queue.clear();
			}
			for (IConsole c : consolesToShow) {
				showConsole(c);
			}
			synchronized (queue) {
				if (!queue.isEmpty()) {
					schedule();
				}
			}
			return Status.OK_STATUS;
		}

		private void showConsole(IConsole c) {
			boolean consoleFound = false;
			IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
			if (window != null && c != null) {
				IWorkbenchPage page = window.getActivePage();
				if (page != null) {
					synchronized (fConsoleViews) {
						for (IConsoleView consoleView : fConsoleViews) {
							if (consoleView.getSite().getPage().equals(page)) {
								boolean consoleVisible = page.isPartVisible(consoleView);
								if (consoleVisible) {
									consoleFound = true;
									boolean bringToTop = shouldBringToTop(c, consoleView);
									if (bringToTop) {
										page.bringToTop(consoleView);
									}
									consoleView.display(c);
								}
							}
						}
					}

					if (!consoleFound) {
						try {
							IConsoleView consoleView = (IConsoleView) page.showView(IConsoleConstants.ID_CONSOLE_VIEW, null, IWorkbenchPage.VIEW_CREATE);
							boolean bringToTop = shouldBringToTop(c, consoleView);
							if (bringToTop) {
								page.bringToTop(consoleView);
							}
							consoleView.display(c);
						} catch (PartInitException pie) {
							ConsolePlugin.log(pie);
						}
					}
				}
			}
		}
	}

	private ShowConsoleViewJob showJob = new ShowConsoleViewJob();
	/**
	 * @see IConsoleManager#showConsoleView(IConsole)
	 */
	@Override
	public void showConsoleView(final IConsole console) {
		showJob.addConsole(console);
		showJob.schedule(100);
	}

	/**
	 * Returns whether the given console view should be brought to the top.
	 * The view should not be brought to the top if the view is pinned on
	 * a console other than the given console.
	 */
	private boolean shouldBringToTop(IConsole console, IViewPart consoleView) {
		boolean bringToTop= true;
		if (consoleView instanceof IConsoleView) {
			IConsoleView cView= (IConsoleView)consoleView;
			if (cView.isPinned()) {
				IConsole pinnedConsole= cView.getConsole();
				bringToTop = console.equals(pinnedConsole);
			}
		}
		return bringToTop;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.IConsoleManager#warnOfContentChange(org.eclipse.ui.console.IConsole)
	 */
	@Override
	public void warnOfContentChange(final IConsole console) {
		if (!fWarnQueued) {
			fWarnQueued = true;
			Job job = new UIJob(ConsolePlugin.getStandardDisplay(), ConsoleMessages.ConsoleManager_consoleContentChangeJob) {
				@Override
				public IStatus runInUIThread(IProgressMonitor monitor) {
					IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
					if (window != null) {
						IWorkbenchPage page= window.getActivePage();
						if (page != null) {
							IConsoleView consoleView= (IConsoleView)page.findView(IConsoleConstants.ID_CONSOLE_VIEW);
							if (consoleView != null) {
								consoleView.warnOfContentChange(console);
							}
						}
					}
					fWarnQueued = false;
					return Status.OK_STATUS;
				}
			};
			job.setSystem(true);
			job.schedule();
		}
	}

    /* (non-Javadoc)
     * @see org.eclipse.ui.console.IConsoleManager#getPatternMatchListenerDelegates(org.eclipse.ui.console.IConsole)
     */
    @Override
	public IPatternMatchListener[] createPatternMatchListeners(IConsole console) {
    		if (fPatternMatchListeners == null) {
			fPatternMatchListeners = new ArrayList<PatternMatchListenerExtension>();
    			IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(ConsolePlugin.getUniqueIdentifier(), IConsoleConstants.EXTENSION_POINT_CONSOLE_PATTERN_MATCH_LISTENERS);
    			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
    			for (int i = 0; i < elements.length; i++) {
    				IConfigurationElement config = elements[i];
    				PatternMatchListenerExtension extension = new PatternMatchListenerExtension(config);
    				fPatternMatchListeners.add(extension);
    			}
    		}
		ArrayList<PatternMatchListener> list = new ArrayList<PatternMatchListener>();
		for (Iterator<PatternMatchListenerExtension> i = fPatternMatchListeners.iterator(); i.hasNext();) {
    		    PatternMatchListenerExtension extension = i.next();
                try {
                    if (extension.getEnablementExpression() == null) {
                        i.remove();
                        continue;
                    }

    		        if (console instanceof TextConsole && extension.isEnabledFor(console)) {
                        TextConsole textConsole = (TextConsole) console;
    		            PatternMatchListener patternMatchListener = new PatternMatchListener(extension);
                        try {
                            textConsole.addPatternMatchListener(patternMatchListener);
                            list.add(patternMatchListener);
                        } catch (PatternSyntaxException e) {
                            ConsolePlugin.log(e);
                            i.remove();
                        }
    		        }
    		    } catch (CoreException e) {
    		        ConsolePlugin.log(e);
    		    }
    		}
        return list.toArray(new PatternMatchListener[0]);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.console.IConsoleManager#getPageParticipants(org.eclipse.ui.console.IConsole)
     */
    public IConsolePageParticipant[] getPageParticipants(IConsole console) {
        if(fPageParticipants == null) {
			fPageParticipants = new ArrayList<ConsolePageParticipantExtension>();
            IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(ConsolePlugin.getUniqueIdentifier(), IConsoleConstants.EXTENSION_POINT_CONSOLE_PAGE_PARTICIPANTS);
            IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
            for(int i = 0; i < elements.length; i++) {
                IConfigurationElement config = elements[i];
                ConsolePageParticipantExtension extension = new ConsolePageParticipantExtension(config);
                fPageParticipants.add(extension);
            }
        }
		ArrayList<IConsolePageParticipant> list = new ArrayList<IConsolePageParticipant>();
		for (Iterator<ConsolePageParticipantExtension> i = fPageParticipants.iterator(); i.hasNext();) {
            ConsolePageParticipantExtension extension = i.next();
            try {
                if (extension.isEnabledFor(console)) {
                    list.add(extension.createDelegate());
                }
            } catch (CoreException e) {
                ConsolePlugin.log(e);
            }
        }
        return list.toArray(new IConsolePageParticipant[0]);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.console.IConsoleManager#getConsoleFactories()
     */
    public ConsoleFactoryExtension[] getConsoleFactoryExtensions() {
        if (fConsoleFactoryExtensions == null) {
			fConsoleFactoryExtensions = new ArrayList<ConsoleFactoryExtension>();
            IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(ConsolePlugin.getUniqueIdentifier(), IConsoleConstants.EXTENSION_POINT_CONSOLE_FACTORIES);
            IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
            for (int i = 0; i < configurationElements.length; i++) {
                fConsoleFactoryExtensions.add(new ConsoleFactoryExtension(configurationElements[i]));
            }
        }
        return fConsoleFactoryExtensions.toArray(new ConsoleFactoryExtension[0]);
    }


    @Override
	public void refresh(final IConsole console) {
        fRepaintJob.addConsole(console);
        fRepaintJob.schedule(50);
    }

}
