/*******************************************************************************
 * Copyright (c) 2008, 2020 SAP AG, 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:
 *    SAP AG - initial API and implementation
 *    Andrew Johnson (IBM Corporation) - comparisons
 *******************************************************************************/
package org.eclipse.mat.ui.snapshot.panes;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.internal.snapshot.SnapshotQueryContext;
import org.eclipse.mat.query.IResult;
import org.eclipse.mat.query.annotations.Category;
import org.eclipse.mat.query.registry.CommandLine;
import org.eclipse.mat.query.registry.QueryDescriptor;
import org.eclipse.mat.query.registry.QueryRegistry;
import org.eclipse.mat.query.registry.QueryResult;
import org.eclipse.mat.report.SpecFactory;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.SnapshotInfo;
import org.eclipse.mat.ui.MemoryAnalyserPlugin;
import org.eclipse.mat.ui.Messages;
import org.eclipse.mat.ui.QueryExecution;
import org.eclipse.mat.ui.editor.AbstractEditorPane;
import org.eclipse.mat.ui.editor.AbstractPaneJob;
import org.eclipse.mat.ui.editor.EditorPaneRegistry;
import org.eclipse.mat.ui.editor.MultiPaneEditorSite;
import org.eclipse.mat.ui.snapshot.editor.HeapEditor;
import org.eclipse.mat.ui.snapshot.editor.HeapEditorPane;
import org.eclipse.mat.ui.util.ErrorHelper;
import org.eclipse.mat.ui.util.ProgressMonitorWrapper;
import org.eclipse.mat.util.MessageUtil;
import org.eclipse.mat.util.Units;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.cheatsheets.OpenCheatSheetAction;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;

public class OverviewPane extends HeapEditorPane implements IHyperlinkListener, ISelectionProvider
{
    private List<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>();
    private ISelectionProvider delegate;

    private FormToolkit toolkit;
    private AbstractEditorPane pane;
    private ScrolledForm form;

    public void createPartControl(Composite parent)
    {
        toolkit = new FormToolkit(parent.getDisplay());
        form = toolkit.createScrolledForm(parent);

        // TableWrapLayout tends to give vertical scroll bars when needed
        // but fits into horizontal space where possible
        TableWrapLayout layout = new TableWrapLayout();
        layout.numColumns = 3;
        layout.verticalSpacing = 20;
        form.getBody().setLayout(layout);

        Section section = createDetailsSection();
        TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 3);
        section.setLayoutData(td);

        section = createBiggestObjectsSection();
        td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 3);
        section.setLayoutData(td);

        section = createSidecarSection();
        if (section != null)
        {
            td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 3);
            section.setLayoutData(td);
        }

        section = createActionSection();
        td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 1);
        section.setLayoutData(td);

        section = createReportsSection();
        td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 1);
        section.setLayoutData(td);

        section = createStepByStepSection();
        td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB, 1, 1);
        section.setLayoutData(td);

        form.reflow(true);
    }

    // //////////////////////////////////////////////////////////////
    // details
    // //////////////////////////////////////////////////////////////

    private Section createSidecarSection()
    {
        Section section = null;
        FormText text = null;

        List<QueryDescriptor> queries = QueryRegistry.instance().getQueries(Pattern.compile("supplement_.*")); //$NON-NLS-1$
        if (queries.isEmpty())
            return null;

        Collections.sort(queries, new Comparator<QueryDescriptor>()
        {
            public int compare(QueryDescriptor o1, QueryDescriptor o2)
            {
                return o1.getName().compareTo(o2.getName());
            }
        });

        StringBuilder buf = new StringBuilder();
        buf.append("<form>");//$NON-NLS-1$
        for (QueryDescriptor query : queries)
        {
            if (query.accept(getQueryContext()))
            {
                if (section == null)
                {
                    section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED
                                    | Section.TWISTIE);
                    section.setText(Messages.OverviewPane_AdditionalInfo);
                    Composite sectionClient = toolkit.createComposite(section);
                    sectionClient.setLayout(new TableWrapLayout());
                    text = toolkit.createFormText(sectionClient, true);
                    text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
                    text.addHyperlinkListener(this);

                    section.setClient(sectionClient);
                }

                addButton(buf, text, query.getIdentifier(), null, query.getName(), query.getHelp());
            }
        }
        buf.append("</form>");//$NON-NLS-1$

        if (text != null)
            text.setText(buf.toString(), true, false);

        return section;
    }

    private Section createDetailsSection()
    {
        Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
        section.setText(Messages.OverviewPane_Details);
        Composite sectionClient = toolkit.createComposite(section);
        sectionClient.setLayout(new TableWrapLayout());
        FormText text = toolkit.createFormText(sectionClient, true);
        text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));

        SnapshotInfo info = getSnapshotInput().getSnapshot().getSnapshotInfo();

        StringBuilder buf = new StringBuilder();
        buf.append("<form>");//$NON-NLS-1$

        buf.append("<p>" + Messages.OverviewPane_Size);//$NON-NLS-1$
        long heapSize = info.getUsedHeapSize();
        String size = Units.Storage.of(heapSize).format(heapSize);
        buf.append("<b>" + size + "</b>");//$NON-NLS-1$//$NON-NLS-2$

        buf.append("  " + Messages.OverviewPane_Classes); //$NON-NLS-1$
        buf.append("<b>" + formatNumber(info.getNumberOfClasses()) + "</b>");//$NON-NLS-1$//$NON-NLS-2$

        buf.append("  " + Messages.OverviewPane_Objects); //$NON-NLS-1$
        buf.append("<b>" + formatNumber(info.getNumberOfObjects()) + "</b>");//$NON-NLS-1$//$NON-NLS-2$

        buf.append("  " + Messages.OverviewPane_ClassLoader); //$NON-NLS-1$
        buf.append("<b>" + formatNumber(info.getNumberOfClassLoaders()) + "</b>");//$NON-NLS-1$//$NON-NLS-2$

        QueryDescriptor descriptor = QueryRegistry.instance().getQuery("unreachable_objects"); //$NON-NLS-1$
        if (descriptor != null && descriptor.accept(getQueryContext()))
        {
            buf.append("  <a href=\"").append(descriptor.getIdentifier()) // //$NON-NLS-1$
                            .append("\">").append(descriptor.getName()).append("</a>");//$NON-NLS-1$//$NON-NLS-2$
        }

        buf.append("</p></form>");//$NON-NLS-1$
        text.setText(buf.toString(), true, false);
        text.addHyperlinkListener(this);

        section.setClient(sectionClient);
        return section;
    }

    private String formatNumber(int number)
    {
        return Units.Plain.of(number).format(number);
    }

    // //////////////////////////////////////////////////////////////
    // actions
    // //////////////////////////////////////////////////////////////

    private Section createActionSection()
    {
        Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
        section.setText(Messages.OverviewPane_Actions);

        Composite sectionClient = toolkit.createComposite(section);
        sectionClient.setLayout(new TableWrapLayout());

        FormText text = toolkit.createFormText(sectionClient, true);
        text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
        StringBuilder buf = new StringBuilder();
        buf.append("<form>");//$NON-NLS-1$

        addButton(buf, text, "histogram", null, Messages.OverviewPane_Histogram, Messages.OverviewPane_HistogramInfo); //$NON-NLS-1$
        addButton(buf, text, "dominator_tree", null, Messages.OverviewPane_DominatorTree, //$NON-NLS-1$
                        Messages.OverviewPane_DominatorTreeInfo);
        addButton(buf, text, "top_consumers_html", null, Messages.OverviewPane_TopConsumers, //$NON-NLS-1$
                        Messages.OverviewPane_TopConsumersInfo);
        addButton(buf, text, "duplicate_classes", null, Messages.OverviewPane_DuplicateClasses, //$NON-NLS-1$
                        Messages.OverviewPane_DuplicateClassesInfo);

        buf.append("</form>");//$NON-NLS-1$
        text.setText(buf.toString(), true, false);
        text.addHyperlinkListener(this);

        section.setClient(sectionClient);
        return section;
    }

    private Section createReportsSection()
    {
        Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
        section.setText(Messages.OverviewPane_Reports);

        Composite sectionClient = toolkit.createComposite(section);
        sectionClient.setLayout(new TableWrapLayout());

        FormText text = toolkit.createFormText(sectionClient, true);
        StringBuilder buf = new StringBuilder();
        buf.append("<form>");//$NON-NLS-1$

        addReportsByPattern(text, buf, Pattern.compile(".*:suspects"));//$NON-NLS-1$
        addReportsByPattern(text, buf, Pattern.compile(".*:top_components"));//$NON-NLS-1$
        addReportsByPattern2(text, buf, Pattern.compile(".*:suspects2"));//$NON-NLS-1$

        buf.append("</form>");//$NON-NLS-1$
        text.setText(buf.toString(), true, false);
        text.addHyperlinkListener(this);

        section.setClient(sectionClient);
        return section;
    }

    private void addReportsByPattern(FormText text, StringBuilder buf, Pattern pattern)
    {
        for (SpecFactory.Report report : SpecFactory.instance().delegates())
        {
            if (pattern.matcher(report.getExtensionIdentifier()).matches())
                addButton(buf, text, "create_report", "default_report " + report.getExtensionIdentifier(), report//$NON-NLS-1$//$NON-NLS-2$
                                .getName(), report.getDescription());
        }
    }

    private void addReportsByPattern2(FormText text, StringBuilder buf, Pattern pattern)
    {
        for (SpecFactory.Report report : SpecFactory.instance().delegates())
        {
            if (pattern.matcher(report.getExtensionIdentifier()).matches())
            {
                String name = report.getName();
                // Allow hidden category report, but remove category
                if (name.startsWith(Category.HIDDEN + "/")) //$NON-NLS-1$
                    name = name.substring(Category.HIDDEN.length() + 1);
                addButton(buf, text, "create_report", "comparison_report " + report.getExtensionIdentifier(), name, //$NON-NLS-1$//$NON-NLS-2$
                                report.getDescription());
            }
        }
    }

    private Section createStepByStepSection()
    {
        Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
        section.setText(Messages.OverviewPane_StepByStep);

        Composite sectionClient = toolkit.createComposite(section);
        sectionClient.setLayout(new TableWrapLayout());

        FormText text = toolkit.createFormText(sectionClient, true);
        StringBuilder buf = new StringBuilder();
        buf.append("<form>");//$NON-NLS-1$

        addCheatSheetLink(buf, "org.eclipse.mat.tutorials.component_report", Messages.OverviewPane_ComponentReport, //$NON-NLS-1$
                        Messages.OverviewPane_ComponentReportInfo);

        buf.append("</form>");//$NON-NLS-1$
        text.setText(buf.toString(), true, false);
        text.addHyperlinkListener(new IHyperlinkListener()
        {
            public void linkActivated(HyperlinkEvent e)
            {
                new OpenCheatSheetAction(String.valueOf(e.getHref())).run();
            }

            public void linkEntered(HyperlinkEvent e)
            {}

            public void linkExited(HyperlinkEvent e)
            {}
        });

        section.setClient(sectionClient);
        return section;
    }

    private void addCheatSheetLink(StringBuilder buf, String cheatSheetId, String title, String help)
    {
        buf.append("<li style=\"text\" value=\"\">");//$NON-NLS-1$
        buf.append("<a href=\"").append(cheatSheetId).append("\">").append(title).append("</a>");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
        if (help != null)
            buf.append(": ").append(help);//$NON-NLS-1$
        buf.append("</li>");//$NON-NLS-1$
    }

    private void addButton(StringBuilder buf, FormText formText, String commandId, String command, String title,
                    String help)
    {
        QueryDescriptor descriptor = QueryRegistry.instance().getQuery(commandId);
        if (descriptor == null)
            return;

        if (command == null)
            command = descriptor.getIdentifier();

        Image image = MemoryAnalyserPlugin.getDefault().getImage(descriptor);
        if (image != null)
        {
            buf.append("<li style=\"image\" value=\"").append(descriptor.getIdentifier()).append("\">");//$NON-NLS-1$//$NON-NLS-2$
            formText.setImage(descriptor.getIdentifier(), image);
        }
        else
        {
            buf.append("<li style=\"text\" value=\"\">");//$NON-NLS-1$
        }

        buf.append("<a href=\"").append(command).append("\">").append(title).append("</a>");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
        if (help != null)
            buf.append(": ").append(help);//$NON-NLS-1$
        buf.append("</li>");//$NON-NLS-1$
    }

    // //////////////////////////////////////////////////////////////
    // biggest objects
    // //////////////////////////////////////////////////////////////

    private Section createBiggestObjectsSection()
    {
        final Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED
                        | Section.TWISTIE);
        section.setText(Messages.OverviewPane_BiggestObjectsByRetainedSIze);

        final Composite sectionClient = toolkit.createComposite(section);

        if (Platform.getBundle("org.eclipse.mat.chart.ui") == null)//$NON-NLS-1$
        {
            sectionClient.setLayout(new TableWrapLayout());

            FormText text = toolkit.createFormText(sectionClient, true);
            StringBuilder buf = new StringBuilder(256);

            buf.append("<form><li style=\"text\" value=\"\">"); //$NON-NLS-1$
            buf.append(MessageUtil.format(Messages.OverviewPane_NoPieChartAvailable,
                            "dominator_tree", "top_consumers_html")); //$NON-NLS-1$ //$NON-NLS-2$
            buf.append("</li></form>"); //$NON-NLS-1$

            text.setText(buf.toString(), true, false);
            text.addHyperlinkListener(this);
        }
        else
        {
            FillLayout layout = new FillLayout();
            sectionClient.setLayout(layout);

            final ISnapshot snapshot = getSnapshotInput().getSnapshot();

            new AbstractPaneJob(Messages.OverviewPane_ExtractingBigObjects, this)
            {
                @Override
                protected IStatus doRun(IProgressMonitor monitor)
                {
                    try
                    {
                        SnapshotQueryContext ctx = new SnapshotQueryContext(snapshot);
                        final IResult result = CommandLine.execute(ctx, "pie_biggest_objects",//$NON-NLS-1$
                                        new ProgressMonitorWrapper(monitor));

                        sectionClient.getDisplay().asyncExec(new Runnable()
                        {
                            public void run()
                            {
                                try
                                {
                                    pane = EditorPaneRegistry.instance().createNewPane(result, null);

                                    pane.init(getEditorSite(), getEditorInput());
                                    pane.createPartControl(sectionClient);
                                    pane.initWithArgument(new QueryResult(null, "pie_biggest_objects", result));//$NON-NLS-1$
                                    form.reflow(true);

                                    if (pane instanceof ISelectionProvider)
                                    {
                                        delegate = (ISelectionProvider) pane;

                                        for (ISelectionChangedListener l : listeners)
                                            delegate.addSelectionChangedListener(l);
                                    }
                                }
                                catch (PartInitException e)
                                {
                                    ErrorHelper.logThrowableAndShowMessage(e);
                                }
                            }
                        });

                        return Status.OK_STATUS;
                    }
                    catch (SnapshotException e)
                    {
                        return ErrorHelper.createErrorStatus(e);
                    }

                }
            }.schedule();
        }

        section.setClient(sectionClient);
        return section;
    }

    // //////////////////////////////////////////////////////////////
    // hyper-link listener
    // //////////////////////////////////////////////////////////////

    public void linkActivated(HyperlinkEvent e)
    {
        String command = String.valueOf(e.getHref());
        runCommand(command);
    }

    private void runCommand(String command)
    {
        try
        {
            HeapEditor heapEditor = (HeapEditor) ((MultiPaneEditorSite) getSite()).getMultiPageEditor();
            QueryExecution.executeCommandLine(heapEditor, this.getPaneState(), command);
        }
        catch (SnapshotException exp)
        {
            ErrorHelper.logThrowableAndShowMessage(exp);
        }
    }

    public void linkEntered(HyperlinkEvent e)
    {}

    public void linkExited(HyperlinkEvent e)
    {}

    // //////////////////////////////////////////////////////////////
    // misc
    // //////////////////////////////////////////////////////////////

    public String getTitle()
    {
        return Messages.OverviewPane_Overview;
    }

    @Override
    public Image getTitleImage()
    {
        return MemoryAnalyserPlugin.getImage(MemoryAnalyserPlugin.ISharedImages.INFO);
    }

    @Override
    public void setFocus()
    {
        form.setFocus();
    }

    // //////////////////////////////////////////////////////////////
    // selection provider
    // //////////////////////////////////////////////////////////////

    public void addSelectionChangedListener(ISelectionChangedListener listener)
    {
        listeners.add(listener);
        if (delegate != null)
            delegate.addSelectionChangedListener(listener);
    }

    public void removeSelectionChangedListener(ISelectionChangedListener listener)
    {
        listeners.remove(listener);
        if (delegate != null)
            delegate.removeSelectionChangedListener(listener);
    }

    public ISelection getSelection()
    {
        if (delegate != null)
            return delegate.getSelection();
        else
            return StructuredSelection.EMPTY;
    }

    public void setSelection(ISelection selection)
    {}

    @Override
    public void dispose()
    {
        super.dispose();
        if (pane != null)
        {
            pane.dispose();
            pane = null;
        }
    }
}
