/*******************************************************************************
 * Copyright (c) 2000, 2016 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.jdt.internal.ui.text.java.hover;

import java.util.Properties;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;

import org.eclipse.core.resources.IStorage;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.internal.text.html.HTMLPrinter;

import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IInformationControlExtension2;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;

import org.eclipse.ui.IEditorPart;

import org.eclipse.ui.editors.text.EditorsUI;

import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.manipulation.SharedASTProviderCore;

import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.corext.refactoring.nls.AccessorClassReference;
import org.eclipse.jdt.internal.corext.refactoring.nls.NLSHintHelper;

import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.javaeditor.NLSKeyHyperlink;


/**
 * Provides externalized string as hover info for NLS key.
 *
 * @since 3.1
 */
public class NLSStringHover extends AbstractJavaEditorTextHover {


	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
	 */
	@Override
	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
		if (!(getEditor() instanceof JavaEditor))
			return null;

		ITypeRoot je= getEditorInputJavaElement();
		if (je == null)
			return null;

		// Never wait for an AST in UI thread.
		CompilationUnit ast= SharedASTProviderCore.getAST(je, SharedASTProviderCore.WAIT_NO, null);
		if (ast == null)
			return null;

		ASTNode node= NodeFinder.perform(ast, offset, 1);
		if (node instanceof StringLiteral) {
			StringLiteral stringLiteral= (StringLiteral)node;
			return new Region(stringLiteral.getStartPosition(), stringLiteral.getLength());
		} else if (node instanceof SimpleName) {
			SimpleName simpleName= (SimpleName)node;
			return new Region(simpleName.getStartPosition(), simpleName.getLength());
		}

		return null;
	}

	/**
	 * @deprecated see {@link org.eclipse.jface.text.ITextHover#getHoverInfo(ITextViewer, IRegion)}
	 */
	@Deprecated
	@Override
	public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
		NLSHoverControlInput info= internalGetHoverInfo(textViewer, hoverRegion);
		return info == null ? null : info.fInformation;
	}

	/*
	 * @see org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
	 */
	@Override
	public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
		return internalGetHoverInfo(textViewer, hoverRegion);
	}

	/**
	 * Returns the hover input.
	 *
	 * @param textViewer the viewer on which the hover popup should be shown
	 * @param hoverRegion the text range in the viewer which is used to determine the hover display
	 *            information
	 * @return the hover popup display input, or <code>null</code> if none available
	 *
	 * @see #getHoverInfo2(ITextViewer, IRegion)
	 */
	private NLSHoverControlInput internalGetHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
		if (!(getEditor() instanceof JavaEditor))
			return null;

		ITypeRoot je= getEditorInputJavaElement();
		if (je == null)
			return null;

		CompilationUnit ast= SharedASTProviderCore.getAST(je, SharedASTProviderCore.WAIT_ACTIVE_ONLY, null);
		if (ast == null)
			return null;

		ASTNode node= NodeFinder.perform(ast, hoverRegion.getOffset(), hoverRegion.getLength());
		if (!(node instanceof StringLiteral) && !(node instanceof SimpleName))
			return null;

		if (node.getLocationInParent() == QualifiedName.QUALIFIER_PROPERTY)
			return null;

		boolean usedFullyQualifiedName= false;
		IBinding containingClassBinding= null;
		ASTNode containingClass= ASTResolving.findParentType(node);
		if (containingClass instanceof TypeDeclaration) {
			containingClassBinding= ((TypeDeclaration)containingClass).resolveBinding();
			ASTNode parentNode= node.getParent();
			if (parentNode instanceof QualifiedName) {
				IBinding qualifierBinding= (((QualifiedName)parentNode).getQualifier()).resolveBinding();
				if (qualifierBinding != null && containingClassBinding != null) {
					usedFullyQualifiedName= qualifierBinding.getKey().equals(containingClassBinding.getKey());
				}
			}
		}
		AccessorClassReference ref= NLSHintHelper.getAccessorClassReference(ast, hoverRegion, usedFullyQualifiedName);
		if (ref == null)
			return null;

		String identifier= null;
		if (node instanceof StringLiteral) {
			identifier= ((StringLiteral)node).getLiteralValue();
		} else if (!usedFullyQualifiedName && node.getLocationInParent() == QualifiedName.NAME_PROPERTY) {
			identifier= ((SimpleName)node).getIdentifier();
		} else {
			try {
				if (containingClassBinding == null)
					return null;
				IType parentType= (IType)containingClassBinding.getJavaElement();
				if (parentType == null)
					return null;
				String varName= ((SimpleName)node).getIdentifier();
				IField field= parentType.getField(varName);
				if (!"String".equals(Signature.getSignatureSimpleName(field.getTypeSignature()))) //$NON-NLS-1$
					return null;
				Object obj= field.getConstant();
				identifier= obj instanceof String ? ((String)obj).substring(1, ((String)obj).length() - 1) : null;
			} catch (JavaModelException e) {
				return null;
			}
		}
		if (identifier == null)
			return null;

		IStorage propertiesFile;
		try {
			propertiesFile= NLSHintHelper.getResourceBundle(je.getJavaProject(), ref);
			if (propertiesFile == null)
				return new NLSHoverControlInput(toHtml(JavaHoverMessages.NLSStringHover_NLSStringHover_PropertiesFileNotDetectedWarning, "", null, false), (IStorage)null, "", getEditor()); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (JavaModelException ex) {
			return null;
		}

		final String propertiesFileName= propertiesFile.getName();
		Properties properties= null;
		try {
			properties= NLSHintHelper.getProperties(propertiesFile);
		} catch (IllegalArgumentException e) {
			return new NLSHoverControlInput(toHtml(propertiesFileName, JavaHoverMessages.NLSStringHover_NLSStringHover_PropertiesFileCouldNotBeReadWarning, e.getLocalizedMessage(), false),
					propertiesFile, identifier, getEditor());
		}
		if (properties == null)
			return null;
		if (properties.isEmpty())
			return new NLSHoverControlInput(toHtml(propertiesFileName, JavaHoverMessages.NLSStringHover_NLSStringHover_missingKeyWarning, null, false), propertiesFile, "", getEditor()); //$NON-NLS-1$

		String value= properties.getProperty(identifier, null);
		String buffer= toHtml(propertiesFileName, value, null, true);
		return new NLSHoverControlInput(buffer, propertiesFile, identifier, getEditor());
	}

	private String toHtml(String header, String string, String errorString, boolean addPreFormatted) {
		StringBuilder buffer= new StringBuilder();
		HTMLPrinter.addSmallHeader(buffer, header);

		if (string != null) {
			if (addPreFormatted) {
				HTMLPrinter.addParagraph(buffer, ""); //$NON-NLS-1$
				HTMLPrinter.addPreFormatted(buffer, HTMLPrinter.convertToHTMLContent(string));
			} else {
				HTMLPrinter.addParagraph(buffer, string);
			}
			if (errorString != null) {
				HTMLPrinter.addParagraph(buffer, errorString);
			}
		} else {
			HTMLPrinter.addParagraph(buffer, JavaHoverMessages.NLSStringHover_NLSStringHover_missingKeyWarning);
		}

		HTMLPrinter.insertPageProlog(buffer, 0);
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}

	/**
	 * The input for NLS hover.
	 *
	 * @since 3.5
	 */
	private static class NLSHoverControlInput {

		private IStorage fpropertiesFile;
		private String fKeyName;
		private String fInformation;
		private IEditorPart fActiveEditor;

		/**
		 * Creates the NLS hover input.
		 *
		 * @param information the hover info (string with simple HTML)
		 * @param propertiesFile the properties file, or <code>null</code> if not found
		 * @param key the NLS key
		 * @param editor the active editor part
		 */
		public NLSHoverControlInput(String information, IStorage propertiesFile, String key, IEditorPart editor) {
			fInformation= information;
			fpropertiesFile= propertiesFile;
			fKeyName= key;
			fActiveEditor= editor;
		}
	}

	/**
	 * The NLS hover control.
	 *
	 * @since 3.5
	 */
	static class NLSHoverControl extends DefaultInformationControl implements IInformationControlExtension2 {

		/**
		 * The NLS control input.
		 */
		private NLSHoverControlInput fInput;

		/**
		 * Creates a resizable NLS hover control with the given shell as parent.
		 *
		 * @param parent the parent shell
		 * @param tbm the toolbar manager or <code>null</code> if toolbar is not desired
		 */
		public NLSHoverControl(Shell parent, ToolBarManager tbm) {
			super(parent, tbm);

		}

		/**
		 * Creates an NLS hover control with the given shell as parent.
		 *
		 * @param parent the parent shell
		 * @param tooltipAffordanceString the text to be used in the status field or
		 *            <code>null</code> to hide the status field
		 */
		public NLSHoverControl(Shell parent, String tooltipAffordanceString) {
			super(parent, tooltipAffordanceString);
		}

		/**
		 * {@inheritDoc} This control can handle {@link NLSStringHover.NLSHoverControlInput}.
		 */
		@Override
		public void setInput(Object input) {
			Assert.isLegal(input instanceof NLSHoverControlInput);

			NLSHoverControlInput info= (NLSHoverControlInput)input;
			setInformation(info.fInformation);
			fInput= info;
		}

		/**
		 * Returns the control input.
		 *
		 * @return the control input
		 */
		public NLSHoverControlInput getInput() {
			return fInput;
		}
	}

	/**
	 * Presenter control creator.
	 *
	 * @since 3.5
	 */
	private static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
		/*
		 * @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
		 */
		@Override
		public IInformationControl doCreateInformationControl(Shell parent) {
			ToolBarManager tbm= new ToolBarManager(SWT.FLAT);
			NLSHoverControl iControl= new NLSHoverControl(parent, tbm);
			OpenPropertiesFileAction openPropertiesFileAction= new OpenPropertiesFileAction(iControl);
			tbm.add(openPropertiesFileAction);
			tbm.update(true);
			return iControl;
		}
	}

	/**
	 * Hover control creator.
	 *
	 * @since 3.5
	 */
	private static final class HoverControlCreator extends AbstractReusableInformationControlCreator {

		/**
		 * The presenter control creator.
		 */
		private final IInformationControlCreator fPresenterControlCreator;

		/**
		 * Creates the hover control creator.
		 *
		 * @param presenterControlCreator the presenter control creator
		 */
		public HoverControlCreator(IInformationControlCreator presenterControlCreator) {
			fPresenterControlCreator= presenterControlCreator;
		}

		/*
		 * @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
		 */
		@Override
		public IInformationControl doCreateInformationControl(Shell parent) {
			return new NLSHoverControl(parent, EditorsUI.getTooltipAffordanceString()) {
				/*
				 * @see org.eclipse.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
				 */
				@Override
				public IInformationControlCreator getInformationPresenterControlCreator() {
					return fPresenterControlCreator;
				}
			};
		}
	}

	/**
	 * The hover control creator.
	 *
	 * @since 3.5
	 */
	private IInformationControlCreator fHoverControlCreator;

	/**
	 * The presentation control creator.
	 *
	 * @since 3.5
	 */
	private IInformationControlCreator fPresenterControlCreator;

	/*
	 * @see ITextHoverExtension#getHoverControlCreator()
	 * @since 3.5
	 */
	@Override
	public IInformationControlCreator getHoverControlCreator() {
		if (fHoverControlCreator == null)
			fHoverControlCreator= new HoverControlCreator(getInformationPresenterControlCreator());
		return fHoverControlCreator;
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover#getInformationPresenterControlCreator()
	 * @since 3.5
	 */
	@Override
	public IInformationControlCreator getInformationPresenterControlCreator() {
		if (fPresenterControlCreator == null)
			fPresenterControlCreator= new PresenterControlCreator();
		return fPresenterControlCreator;
	}


	/**
	 * Action that opens the current hover NLS string in properties file.
	 *
	 * @since 3.5
	 */
	private static final class OpenPropertiesFileAction extends Action {

		/**
		 * The NLS hover control.
		 */
		private NLSHoverControl fControl;

		/**
		 * Creates the action for opening properties file.
		 *
		 * @param control the NLS hover control
		 */
		public OpenPropertiesFileAction(NLSHoverControl control) {
			fControl= control;
			setText(JavaHoverMessages.NLSStringHover_open_in_properties_file);
			JavaPluginImages.setLocalImageDescriptors(this, "goto_input.png"); //$NON-NLS-1$
		}

		/*
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			NLSHoverControlInput input= fControl.getInput();
			NLSKeyHyperlink.openKeyInPropertiesFile(input.fKeyName, input.fpropertiesFile, input.fActiveEditor);
		}
	}
}
