/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.console;

import java.util.Date;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSStatus;
import org.eclipse.team.internal.ccvs.core.client.Session;
import org.eclipse.team.internal.ccvs.core.client.listeners.IConsoleListener;
import org.eclipse.team.internal.ccvs.ui.*;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.*;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;

/**
 * Console that shows the output of CVS commands. It is shown as a page in the generic 
 * console view. It supports coloring for message, command, and error lines in addition
 * the font can be configured.
 * 
 * @since 3.0 
 */
public class CVSOutputConsole extends MessageConsole implements IConsoleListener, IPropertyChangeListener {
	
	// created colors for each line type - must be disposed at shutdown
	private Color commandColor;
	private Color messageColor;
	private Color errorColor;
	
	// used to time the commands
	private long commandStarted = 0;
	
	// streams for each command type - each stream has its own color
	private MessageConsoleStream commandStream;
	private MessageConsoleStream messageStream;
	private MessageConsoleStream errorStream;
	
	// preferences for showing the cvs console when cvs output is provided 
	private boolean showOnMessage;
	
	private ConsoleDocument document;
	private IConsoleManager consoleManager;
	
	// format for timings printed to console
	private static final DateFormat TIME_FORMAT;
    
    static {
        DateFormat format;
        try {
            format = new SimpleDateFormat(CVSUIMessages.Console_resultTimeFormat); 
        } catch (RuntimeException e) {
            // This can happen if the bundle contains an invalid  format
            format = new SimpleDateFormat("'(took 'm:ss.SSS')')"); //$NON-NLS-1$
        }
        TIME_FORMAT = format;
    }

	// Indicates whether the console is visible in the Console view
	private boolean visible = false;
	// Indicates whether the console's streams have been initialized
	private boolean initialized = false;
	
	/*
	 * Constant used for indenting error status printing
	 */
    private static final String NESTING = "   "; //$NON-NLS-1$
	
	/**
	 * Used to notify this console of lifecycle methods <code>init()</code>
	 * and <code>dispose()</code>.
	 */
	public class MyLifecycle implements org.eclipse.ui.console.IConsoleListener {
		@Override
		public void consolesAdded(IConsole[] consoles) {
			for (int i = 0; i < consoles.length; i++) {
				IConsole console = consoles[i];
				if (console == CVSOutputConsole.this) {
					init();
				}
			}

		}
		@Override
		public void consolesRemoved(IConsole[] consoles) {
			for (int i = 0; i < consoles.length; i++) {
				IConsole console = consoles[i];
				if (console == CVSOutputConsole.this) {
					ConsolePlugin.getDefault().getConsoleManager().removeConsoleListener(this);
					dispose();
				}
			}
		}
	}
	
	/**
	 * Constructor initializes preferences and colors but doesn't create the console
	 * page yet.
	 */
	public CVSOutputConsole() {
		super("CVS", CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_CVS_CONSOLE)); //$NON-NLS-1$
		showOnMessage = CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_CONSOLE_SHOW_ON_MESSAGE);
		document = new ConsoleDocument();
		consoleManager = ConsolePlugin.getDefault().getConsoleManager();
		CVSProviderPlugin.getPlugin().setConsoleListener(CVSOutputConsole.this);
		CVSUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(CVSOutputConsole.this);
	}
	
	@Override
	protected void init() {
		// Called when console is added to the console view
		super.init();	
		
		initLimitOutput();
		initWrapSetting();
		
		//	Ensure that initialization occurs in the ui thread
		CVSUIPlugin.getStandardDisplay().asyncExec(() -> {
			JFaceResources.getFontRegistry().addListener(CVSOutputConsole.this);
			initializeStreams();
			dump();
		});
	}
	
	private void initWrapSetting() {
		IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore();
		if(store.getBoolean(ICVSUIConstants.PREF_CONSOLE_WRAP)) {
			setConsoleWidth(store.getInt(ICVSUIConstants.PREF_CONSOLE_WIDTH));
		} else {
			setConsoleWidth(-1);
		}
	}
	
	private void initLimitOutput() {
		IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore();
		if(store.getBoolean(ICVSUIConstants.PREF_CONSOLE_LIMIT_OUTPUT)) {
			setWaterMarks(1000, store.getInt(ICVSUIConstants.PREF_CONSOLE_HIGH_WATER_MARK));
		} else {
			setWaterMarks(-1, 0);
		}
	}
	
	/*
	 * Initialize thre streams of the console. Must be 
	 * called from the UI thread.
	 */
	private void initializeStreams() {
		synchronized(document) {
			if (!initialized) {
				commandStream = newMessageStream();
				errorStream = newMessageStream();
				messageStream = newMessageStream();
				// install colors
				commandColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_COMMAND_COLOR);
				commandStream.setColor(commandColor);
				messageColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_MESSAGE_COLOR);
				messageStream.setColor(messageColor);
				errorColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_ERROR_COLOR);
				errorStream.setColor(errorColor);
				// install font
				Font f = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getFontRegistry().get(ICVSUIConstants.PREF_CONSOLE_FONT);
				setFont(f);
				initialized = true;
			}
		}
	}

	private void dump() {
		synchronized(document) {
			visible = true;
			ConsoleDocument.ConsoleLine[] lines = document.getLines();
			for (int i = 0; i < lines.length; i++) {
				ConsoleDocument.ConsoleLine line = lines[i];
				appendLine(line.type, line.line);
			}
			document.clear();
		}
	}
	
	private void appendLine(int type, String line) {
		showConsole();
		synchronized(document) {
			if(visible) {
				switch(type) {
					case ConsoleDocument.COMMAND:
						commandStream.println(line);
						break;
					case ConsoleDocument.MESSAGE:
						messageStream.println("  " + line); //$NON-NLS-1$
						break;
					case ConsoleDocument.ERROR:
						errorStream.println("  " + line); //$NON-NLS-1$
						break;
				}
			} else {
				document.appendConsoleLine(type, line);
			}
		}
	}

    private void showConsole() {
		show(false);
	}
	
	@Override
	protected void dispose() {
		// Here we can't call super.dispose() because we actually want the partitioner to remain
		// connected, but we won't show lines until the console is added to the console manager
		// again.
		
		// Called when console is removed from the console view
		synchronized (document) {
			visible = false;
			JFaceResources.getFontRegistry().removeListener(this);
		}
	}
	
	/**
	 * Clean-up created fonts.
	 */
	public void shutdown() {
		// Call super dispose because we want the partitioner to be
		// disconnected.
		super.dispose();
		if (commandColor != null)
			commandColor.dispose();
		if (messageColor != null)
			messageColor.dispose();
		if (errorColor != null)
			errorColor.dispose();
		CVSUIPlugin.getPlugin().getPreferenceStore().removePropertyChangeListener(this);
	}

	@Override
	public void commandInvoked(Session session, String line) {
	    if (!session.isOutputToConsole()) return;
		commandStarted = System.currentTimeMillis();
		appendLine(ConsoleDocument.COMMAND, CVSUIMessages.Console_preExecutionDelimiter); 
		appendLine(ConsoleDocument.COMMAND, line);
	}

	@Override
	public void messageLineReceived(Session session, String line, IStatus status) {
	    if (session.isOutputToConsole()) {
	        appendLine(ConsoleDocument.MESSAGE, "  " + line); //$NON-NLS-1$
	    }
	}

	@Override
	public void errorLineReceived(Session session, String line, IStatus status) {
	    if (session.isOutputToConsole()) {
	        appendLine(ConsoleDocument.ERROR, "  " + line); //$NON-NLS-1$
	    }
	}
	
	@Override
	public void commandCompleted(Session session, IStatus status, Exception exception) {
	    if (!session.isOutputToConsole()) return;
		long commandRuntime = System.currentTimeMillis() - commandStarted;
		String time;
		try {
			time = TIME_FORMAT.format(new Date(commandRuntime));
		} catch (RuntimeException e) {
			CVSUIPlugin.log(IStatus.ERROR, CVSUIMessages.Console_couldNotFormatTime, e); 
			time = ""; //$NON-NLS-1$
		}
		String statusText;
		if (status != null) {
		    boolean includeRoot = true;
			if (status.getCode() == CVSStatus.SERVER_ERROR) {
				statusText = NLS.bind(CVSUIMessages.Console_resultServerError, new String[] { status.getMessage(), time }); 
				includeRoot = false;
			} else {
				statusText = NLS.bind(CVSUIMessages.Console_resultOk, new String[] { time }); 
			}
			appendLine(ConsoleDocument.COMMAND, statusText);
			outputStatus(status, includeRoot, includeRoot ? 0 : 1);
		} else if (exception != null) {
			if (exception instanceof OperationCanceledException) {
				statusText = NLS.bind(CVSUIMessages.Console_resultAborted, new String[] { time }); 
			} else {
				statusText = NLS.bind(CVSUIMessages.Console_resultException, new String[] { time }); 
			}
			appendLine(ConsoleDocument.COMMAND, statusText);
			if (exception instanceof CoreException) {
			    outputStatus(((CoreException)exception).getStatus(), true, 1);
			}
		} else {
			statusText = NLS.bind(CVSUIMessages.Console_resultOk, new String[] { time }); 
		}
		appendLine(ConsoleDocument.COMMAND, CVSUIMessages.Console_postExecutionDelimiter); 
		appendLine(ConsoleDocument.COMMAND, ""); //$NON-NLS-1$
	}
	
	private void outputStatus(IStatus status, boolean includeParent, int nestingLevel) {
		if (includeParent && !status.isOK()) {
            outputStatusMessage(status, nestingLevel);
            nestingLevel++;
		}
		
		// Include a CoreException in the status
		Throwable t = status.getException();
		if (t instanceof CoreException) {
		    outputStatus(((CoreException)t).getStatus(), true, nestingLevel);
		}
		
		// Include child status
		IStatus[] children = status.getChildren();
		for (int i = 0; i < children.length; i++) {
			outputStatus(children[i], true, nestingLevel);
		}
	}
	
    private void outputStatusMessage(IStatus status, int nesting) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < nesting; i++) {
            buffer.append(NESTING);
        }
        buffer.append(messageLineForStatus(status));
        appendLine(ConsoleDocument.COMMAND, buffer.toString());
    }

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();
		// colors
		if (visible) {
			if (property.equals(ICVSUIConstants.PREF_CONSOLE_COMMAND_COLOR)) {
				Color newColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_COMMAND_COLOR);
				commandStream.setColor(newColor);
				commandColor.dispose();
				commandColor = newColor;
			} else if (property.equals(ICVSUIConstants.PREF_CONSOLE_MESSAGE_COLOR)) {
				Color newColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_MESSAGE_COLOR);
				messageStream.setColor(newColor);
				messageColor.dispose();
				messageColor = newColor;
			} else if (property.equals(ICVSUIConstants.PREF_CONSOLE_ERROR_COLOR)) {
				Color newColor = createColor(CVSUIPlugin.getStandardDisplay(), ICVSUIConstants.PREF_CONSOLE_ERROR_COLOR);
				errorStream.setColor(newColor);
				errorColor.dispose();
				errorColor = newColor;
				// font
			} else if (property.equals(ICVSUIConstants.PREF_CONSOLE_FONT)) {
				setFont(((FontRegistry) event.getSource()).get(ICVSUIConstants.PREF_CONSOLE_FONT));
			}
		}
		if (property.equals(ICVSUIConstants.PREF_CONSOLE_SHOW_ON_MESSAGE)) {
			Object value = event.getNewValue();
			if (value instanceof String) {
				showOnMessage = Boolean.valueOf((String) value).booleanValue();
			} else {
				showOnMessage = ((Boolean) value).booleanValue();
			}
		} else if(property.equals(ICVSUIConstants.PREF_CONSOLE_LIMIT_OUTPUT)) {
			initLimitOutput();
		} else if(property.equals(ICVSUIConstants.PREF_CONSOLE_WRAP)) {
			initWrapSetting();
		}
	}
	
	/**
	 * Returns the NLSd message based on the status returned from the CVS
	 * command.
	 * 
	 * @param status an NLSd message based on the status returned from the CVS
	 * command.
	 */
	private String messageLineForStatus(IStatus status) {
		if (status.getSeverity() == IStatus.ERROR) {
			return NLS.bind(CVSUIMessages.Console_error, new String[] { status.getMessage() }); 
		} else if (status.getSeverity() == IStatus.WARNING) {
			return NLS.bind(CVSUIMessages.Console_warning, new String[] { status.getMessage() }); 
		} else if (status.getSeverity() == IStatus.INFO) {
			return NLS.bind(CVSUIMessages.Console_info, new String[] { status.getMessage() }); 
		}
		return status.getMessage();
	}
	
	/**
	 * Returns a color instance based on data from a preference field.
	 */
	private Color createColor(Display display, String preference) {
		RGB rgb = PreferenceConverter.getColor(CVSUIPlugin.getPlugin().getPreferenceStore(), preference);
		return new Color(display, rgb);
	}

    /**
     * Show the console.
     * @param showNoMatterWhat ignore preferences if <code>true</code>
     */
    public void show(boolean showNoMatterWhat) {
		if(showNoMatterWhat || showOnMessage) {
			if(!visible)
				CVSConsoleFactory.showConsole();
			else
				consoleManager.showConsoleView(this);
		}
    }
    
    @Override
	public String getHelpContextId() {
    	return IHelpContextIds.CONSOLE_VIEW;
    }
}
