/*******************************************************************************
 * Copyright (c) 2000, 2012 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:
 *   Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation
 * 			(report 36180: Callers/Callees view)
 *   Stephan Herrmann (stephan@cs.tu-berlin.de):
 *          - bug 75800: [call hierarchy] should allow searches for fields
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.callhierarchy;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;

import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;

import org.eclipse.ui.texteditor.ITextEditor;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy;
import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation;
import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaUI;

import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;

public class CallHierarchyUI {
    private static final int DEFAULT_MAX_CALL_DEPTH= 10;
    private static final String PREF_MAX_CALL_DEPTH = "PREF_MAX_CALL_DEPTH"; //$NON-NLS-1$

    private static CallHierarchyUI fgInstance;
    private int fViewCount= 0;
    private final List<IMember[]> fMethodHistory= new ArrayList<>();

	/**
	 * List of the Call Hierarchy views in LRU order, where the most recently used view is at index 0.
	 * @since 3.7
	 */
	private List<CallHierarchyViewPart> fLRUCallHierarchyViews= new ArrayList<>();

    private CallHierarchyUI() {
        // Do nothing
    }

    public static CallHierarchyUI getDefault() {
        if (fgInstance == null) {
            fgInstance = new CallHierarchyUI();
        }

        return fgInstance;
    }

    /**
     * Returns the maximum tree level allowed
     * @return int
     */
    public int getMaxCallDepth() {
        int maxCallDepth;

        IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore();
        maxCallDepth = settings.getInt(PREF_MAX_CALL_DEPTH);
        if (maxCallDepth < 1 || maxCallDepth > 99) {
            maxCallDepth= DEFAULT_MAX_CALL_DEPTH;
        }

        return maxCallDepth;
    }

    public void setMaxCallDepth(int maxCallDepth) {
        IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore();
        settings.setValue(PREF_MAX_CALL_DEPTH, maxCallDepth);
    }

    public static void jumpToMember(IJavaElement element) {
        if (element != null) {
            try {
                JavaUI.openInEditor(element, true, true);
            } catch (JavaModelException e) {
                JavaPlugin.log(e);
            } catch (PartInitException e) {
                JavaPlugin.log(e);
            }
        }
    }

    public static void jumpToLocation(CallLocation callLocation) {
        try {
            IEditorPart methodEditor = JavaUI.openInEditor(callLocation.getMember(), false, false);
            if (methodEditor instanceof ITextEditor) {
                ITextEditor editor = (ITextEditor) methodEditor;
                editor.selectAndReveal(callLocation.getStart(),
                    (callLocation.getEnd() - callLocation.getStart()));
            }
        } catch (JavaModelException e) {
            JavaPlugin.log(e);
        } catch (PartInitException e) {
            JavaPlugin.log(e);
        }
    }

	/**
	 * Opens the element in the editor or shows an error dialog if that fails.
	 *
	 * @param element the element to open
	 * @param shell parent shell for error dialog
	 * @param activateOnOpen <code>true</code> if the editor should be activated
	 * @return <code>true</code> iff no error occurred while trying to open the editor,
	 *         <code>false</code> iff an error dialog was raised.
	 */
	public static boolean openInEditor(Object element, Shell shell, boolean activateOnOpen) {
        CallLocation callLocation= CallHierarchy.getCallLocation(element);

        try {
	        IMember enclosingMember;
	        int selectionStart;
			int selectionLength;

	        if (callLocation != null) {
				enclosingMember= callLocation.getMember();
				selectionStart= callLocation.getStart();
				selectionLength= callLocation.getEnd() - selectionStart;
	        } else if (element instanceof MethodWrapper) {
	        	enclosingMember= ((MethodWrapper) element).getMember();
	        	ISourceRange selectionRange= enclosingMember.getNameRange();
	        	if (selectionRange == null)
	        		selectionRange= enclosingMember.getSourceRange();
	        	if (selectionRange == null)
	        		return true;
	        	selectionStart= selectionRange.getOffset();
	        	selectionLength= selectionRange.getLength();
	        } else {
	            return true;
	        }

			IEditorPart methodEditor = JavaUI.openInEditor(enclosingMember, activateOnOpen, false);
            if (methodEditor instanceof ITextEditor) {
                ITextEditor editor = (ITextEditor) methodEditor;
				editor.selectAndReveal(selectionStart, selectionLength);
            }
            return true;
        } catch (JavaModelException e) {
            JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),
                    IJavaStatusConstants.INTERNAL_ERROR,
                    CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message, e));

            ErrorDialog.openError(shell, CallHierarchyMessages.OpenLocationAction_error_title,
                CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message,
                e.getStatus());
            return false;
        } catch (PartInitException x) {
            String name;
        	if (callLocation != null)
        		name= callLocation.getCalledMember().getElementName();
        	else if (element instanceof MethodWrapper)
        		name= ((MethodWrapper) element).getName();
        	else
        		name= "";  //$NON-NLS-1$
            MessageDialog.openError(shell, CallHierarchyMessages.OpenLocationAction_error_title,
                Messages.format(
                    CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_messageArgs,
                    new String[] { name, x.getMessage() }));
            return false;
        }
    }

    public static IEditorPart isOpenInEditor(Object elem) {
        IJavaElement javaElement= null;
        if (elem instanceof MethodWrapper) {
            javaElement= ((MethodWrapper) elem).getMember();
        } else if (elem instanceof CallLocation) {
            javaElement= ((CallLocation) elem).getMember();
        }
        if (javaElement != null) {
            return EditorUtility.isOpenInEditor(javaElement);
        }
        return null;
    }

    public static CallHierarchyViewPart openSelectionDialog(IMember[] candidates, IWorkbenchWindow window) {
        Assert.isTrue(candidates != null);

        IMember input= null;
        if (candidates.length > 1) {
            String title= CallHierarchyMessages.CallHierarchyUI_selectionDialog_title;
            String message= CallHierarchyMessages.CallHierarchyUI_selectionDialog_message;
            input= (IMember) SelectionConverter.selectJavaElement(candidates, window.getShell(), title, message);
        } else if (candidates.length == 1) {
            input= candidates[0];
        }
        if (input == null)
            return openView(new IMember[] {}, window);

        return openView(new IMember[] { input }, window);
    }

    public static CallHierarchyViewPart openView(IMember[] input, IWorkbenchWindow window) {
    	if (input.length == 0) {
			MessageDialog.openInformation(window.getShell(), CallHierarchyMessages.CallHierarchyUI_selectionDialog_title,
					CallHierarchyMessages.CallHierarchyUI_open_operation_unavialable);
			return null;
		}
        IWorkbenchPage page= window.getActivePage();
		try {
			CallHierarchyViewPart viewPart= getDefault().findLRUCallHierarchyViewPart(page); //find the first view which is not pinned
			String secondaryId= null;
			if (viewPart == null) {
				if (page.findViewReference(CallHierarchyViewPart.ID_CALL_HIERARCHY) != null) //all the current views are pinned, open a new instance
					secondaryId= String.valueOf(++getDefault().fViewCount);
			} else
				secondaryId= viewPart.getViewSite().getSecondaryId();
			viewPart= (CallHierarchyViewPart)page.showView(CallHierarchyViewPart.ID_CALL_HIERARCHY, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
			viewPart.setInputElements(input);
			return viewPart;
        } catch (CoreException e) {
            ExceptionHandler.handle(e, window.getShell(),
                CallHierarchyMessages.CallHierarchyUI_error_open_view, e.getMessage());
        }
        return null;
    }

	/**
	 * Finds the first Call Hierarchy view part instance that is not pinned.
	 * 
	 * @param page the active page
	 * @return the Call Hierarchy view part to open or <code>null</code> if none found
	 * @since 3.7
	 */
	private CallHierarchyViewPart findLRUCallHierarchyViewPart(IWorkbenchPage page) {
		boolean viewFoundInPage= false;
		for (CallHierarchyViewPart view : fLRUCallHierarchyViews) {
			if (page.equals(view.getSite().getPage())) {
				if (!view.isPinned()) {
					return view;
				}
				viewFoundInPage= true;
			}
		}
		if (!viewFoundInPage) {
			// find unresolved views
			for (IViewReference curr : page.getViewReferences()) {
				if (CallHierarchyViewPart.ID_CALL_HIERARCHY.equals(curr.getId()) && page.equals(curr.getPage())) {
					CallHierarchyViewPart view= (CallHierarchyViewPart)curr.getView(true);
					if (view != null && !view.isPinned()) {
						return view;
					}
				}
			}
		}
		return null;
	}

	/**
	 * Adds the activated view part to the head of the list.
	 * 
	 * @param view the Call Hierarchy view part
	 * @since 3.7
	 */
	void callHierarchyViewActivated(CallHierarchyViewPart view) {
		fLRUCallHierarchyViews.remove(view);
		fLRUCallHierarchyViews.add(0, view);
	}

	/**
	 * Removes the closed view part from the list.
	 * 
	 * @param view the closed view part
	 * @since 3.7
	 */
	void callHierarchyViewClosed(CallHierarchyViewPart view) {
		fLRUCallHierarchyViews.remove(view);
	}

    /**
     * Converts an ISelection (containing MethodWrapper instances) to an ISelection
     * with the MethodWrapper's replaced by their corresponding IMembers. If the selection
     * contains elements which are not MethodWrapper instances or not already IMember instances
     * they are discarded.
     * @param selection The selection to convert.
     * @return An ISelection containing IMember's in place of MethodWrapper instances.
     */
    static ISelection convertSelection(ISelection selection) {
        if (selection.isEmpty()) {
            return selection;
        }

        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection= (IStructuredSelection) selection;
            List<IMember> javaElements= new ArrayList<>();
            for (Iterator<?> iter= structuredSelection.iterator(); iter.hasNext();) {
                Object element= iter.next();
                if (element instanceof MethodWrapper) {
                    IMember member= ((MethodWrapper)element).getMember();
                    if (member != null) {
                        javaElements.add(member);
                    }
                } else if (element instanceof IMember) {
                    javaElements.add((IMember) element);
                } else if (element instanceof CallLocation) {
                    IMember member = ((CallLocation) element).getMember();
                    javaElements.add(member);
                }
            }
            return new StructuredSelection(javaElements);
        }
        return StructuredSelection.EMPTY;
    }

	/**
	 * Clears the history and updates all the open views.
	 * 
	 * @since 3.7
	 */
	void clearHistory() {
		for (CallHierarchyViewPart part : fLRUCallHierarchyViews) {
			part.setHistoryEntries(new IMember[0][]);
			part.setInputElements(null);
		}
	}

	/**
	 * Returns the method history.
	 * 
	 * @return the method history
	 * @since 3.7
	 */
	List<IMember[]> getMethodHistory() {
		return fMethodHistory;
	}
}
