/*******************************************************************************
 * Copyright (c) 2017 Ericsson
 *
 * All rights reserved. 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
 *******************************************************************************/

package org.eclipse.tracecompass.tmf.ui.viewers.tree;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.tracecompass.common.core.log.TraceCompassLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderManager;
import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.viewers.ILegendImageProvider;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.MultiTreePatternFilter;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TriStateFilteredCheckboxTree;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.primitives.Longs;

/**
 * Abstract viewer for trees with checkboxes.
 *
 * @since 3.2
 * @author Loic Prieur-Drevon
 */
public abstract class AbstractSelectTreeViewer extends AbstractTmfTreeViewer {

    private static final @NonNull Logger LOGGER = TraceCompassLog.getLogger(AbstractSelectTreeViewer.class);

    /** Timeout between updates in the updateData thread **/
    private static final long BUILD_UPDATE_TIMEOUT = 500;

    /** ID of the checked tree items in the map of data in {@link TmfTraceContext} */
    private static final @NonNull String CHECKED_ELEMENTS = ".CHECKED_ELEMENTS"; //$NON-NLS-1$
    private static final @NonNull String FILTER_STRING = ".FILTER_STRING"; //$NON-NLS-1$
    private static final @NonNull String UPDATE_CONTENT_JOB_NAME = "AbstractSelectTreeViewer#updateContent Job"; //$NON-NLS-1$
    private static final String FAILED_TO_SLEEP_PREFIX = "Failed to sleep the "; //$NON-NLS-1$
    private static final String LOG_CATEGORY_SUFFIX = " Tree viewer"; //$NON-NLS-1$

    private final String fId;
    private final @NonNull String fLogCategory;

    private static final ViewerComparator COMPARATOR = new ViewerComparator() {
        @Override
        public int compare(Viewer viewer, Object e1, Object e2) {
            TmfTreeViewerEntry entry1 = (TmfTreeViewerEntry) e1;
            TmfTreeViewerEntry entry2 = (TmfTreeViewerEntry) e2;
            String name1 = entry1.getName();
            String name2 = entry2.getName();
            Long longValue1 = Longs.tryParse(name1);
            Long longValue2 = Longs.tryParse(name2);

            return (longValue1 == null || longValue2 == null) ? name1.compareTo(name2) : longValue1.compareTo(longValue2);
        }
    };

    private final class CheckStateChangedListener implements ICheckStateListener {
        @Override
        public void checkStateChanged(CheckStateChangedEvent event) {
            saveViewContext();
            if (fChartViewer != null) {
                fChartViewer.handleCheckStateChangedEvent(getCheckedViewerEntries());

                // Legend image might have changed
                refresh();
            }
        }
    }

    private ILegendImageProvider fLegendImageProvider;
    private ICheckboxTreeViewerListener fChartViewer;
    private TriStateFilteredCheckboxTree fCheckboxTree;
    private final int fLegendIndex;

    /**
     * Constructor
     *
     * @param parent
     *            Parent composite
     * @param checkboxTree
     *            <code>TriStateFilteredTree</code> wrapping a
     *            <code>CheckboxTreeViewer</code>
     * @param legendColumnIndex
     *            index of the legend column (-1 if none)
     */
    private AbstractSelectTreeViewer(Composite parent, TriStateFilteredCheckboxTree checkboxTree,
            int legendIndex, String id) {
        super(parent, checkboxTree.getViewer());

        TreeViewer treeViewer = checkboxTree.getViewer();
        treeViewer.setComparator(COMPARATOR);
        if (treeViewer instanceof CheckboxTreeViewer) {
            ((CheckboxTreeViewer) treeViewer).addCheckStateListener(new CheckStateChangedListener());
        }
        checkboxTree.getFilterControl().addModifyListener(e -> saveViewContext());
        fCheckboxTree = checkboxTree;
        fLegendIndex = legendIndex;
        fId = id;
        fLogCategory = fId + LOG_CATEGORY_SUFFIX;
    }

    /**
     * Constructor
     *
     * @param parent
     *            Parent composite
     * @param legendIndex
     *            index of the legend column (-1 if none)
     * @param id
     *            {@link ITmfTreeDataProvider} ID
     */
    public AbstractSelectTreeViewer(Composite parent, int legendIndex, String id) {
        // Create the tree viewer with a filtered checkbox
        this(parent, new TriStateFilteredCheckboxTree(parent,
                SWT.MULTI | SWT.H_SCROLL | SWT.FULL_SELECTION,
                new MultiTreePatternFilter(), true), legendIndex, id);
    }

    /**
     * Tell the chart viewer to listen to changes in the tree viewer
     *
     * @param listener
     *            Chart listening to changes in the tree's selected entries
     */
    public void setTreeListener(ICheckboxTreeViewerListener listener) {
        fChartViewer = listener;
    }

    /**
     * Set the legend image provider (provider tree cells with an image).
     *
     * @param legendImageProvider
     *            Provides an image legend associated with a name
     */
    public void setLegendImageProvider(ILegendImageProvider legendImageProvider) {
        fLegendImageProvider = legendImageProvider;
    }

    /**
     * Return the checked state of an element
     *
     * @param element
     *            the element
     * @return if the element is checked
     */
    public boolean isChecked(Object element) {
        return fCheckboxTree.getChecked(element);
    }

    /**
     * Select previously checked entries when going back to trace.
     */
    @Override
    protected void contentChanged(ITmfTreeViewerEntry rootEntry) {
        ITmfTrace trace = getTrace();
        if (trace == null) {
            return;
        }
        TmfTraceContext ctx = TmfTraceManager.getInstance().getTraceContext(trace);
        Set<Long> ids = (Set<Long>) ctx.getData(getClass() + CHECKED_ELEMENTS);
        if (ids != null && rootEntry != null) {
            List<ITmfTreeViewerEntry> checkedElements = new ArrayList<>();
            checkEntries(ids, rootEntry, checkedElements);
            fCheckboxTree.setCheckedElements(checkedElements.toArray());
        }
        Object filterString = ctx.getData(getClass() + FILTER_STRING);
        if (filterString instanceof String) {
            fCheckboxTree.setFilterText((String) filterString);
        } else {
            fCheckboxTree.setFilterText(""); //$NON-NLS-1$
        }

        if (fChartViewer != null) {
            fChartViewer.handleCheckStateChangedEvent(getCheckedViewerEntries());
        }
        getTreeViewer().refresh();
    }

    private Collection<ITmfTreeViewerEntry> getCheckedViewerEntries() {
        Object[] checkedElements = fCheckboxTree.getCheckedElements();
        return Lists.newArrayList(Iterables.filter(Arrays.asList(checkedElements), ITmfTreeViewerEntry.class));
    }

    /**
     * Recursively find entries which were previously checked and check them again
     * by id.
     *
     * @param ids
     *            Set of previously checked IDs
     * @param root
     *            {@link ITmfTreeViewerEntry} to compare to the set of checked
     *            entries
     * @param checkedElements
     *            list of checked entries to which we add the root entry if it was
     *            previously checked
     */
    private void checkEntries(Set<Long> ids, ITmfTreeViewerEntry root, List<ITmfTreeViewerEntry> checkedElements) {
        if (root instanceof TmfGenericTreeEntry
                && ids.contains(((TmfGenericTreeEntry) root).getModel().getId())) {
            checkedElements.add(root);
        }
        for (ITmfTreeViewerEntry child : root.getChildren()) {
            checkEntries(ids, child, checkedElements);
        }
    }

    @Override
    @TmfSignalHandler
    public void traceOpened(TmfTraceOpenedSignal signal) {
        saveViewContext();
        restorePatternFilter(signal.getTrace());
        fCheckboxTree.setCheckedElements(new Object[0]);
        super.traceOpened(signal);
    }

    @Override
    @TmfSignalHandler
    public void traceSelected(TmfTraceSelectedSignal signal) {
        if (getTrace() != signal.getTrace()) {
            saveViewContext();
            restorePatternFilter(signal.getTrace());
            fCheckboxTree.setCheckedElements(new Object[0]);
        }
        super.traceSelected(signal);
    }

    @Override
    public void reset() {
        fCheckboxTree.setCheckedElements(new Object[0]);
        fCheckboxTree.setFilterText(""); //$NON-NLS-1$
        super.reset();
    }

    @Override
    protected void updateContent(long start, long end, boolean isSelection) {
        try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, UPDATE_CONTENT_JOB_NAME)
                .setCategory(fLogCategory).build()) {
            ITmfTrace trace = getTrace();
            if (trace == null) {
                return;
            }
            Job thread = new Job(UPDATE_CONTENT_JOB_NAME) {
                @Override
                public IStatus run(IProgressMonitor monitor) {
                    try (FlowScopeLog runScope = new FlowScopeLogBuilder(LOGGER, Level.FINE, UPDATE_CONTENT_JOB_NAME + " run") //$NON-NLS-1$
                            .setParentScope(scope).build()) {

                        ITmfTreeDataProvider<@NonNull ITmfTreeDataModel> provider = getProvider(trace);
                        if (provider == null) {
                            return Status.OK_STATUS;
                        }

                        Map<String, Object> parameters = getParameters(start, end, isSelection);
                        if (parameters.isEmpty()) {
                            return Status.OK_STATUS;
                        }

                        boolean isComplete = false;
                        do {
                            TmfModelResponse<@NonNull TmfTreeModel<@NonNull ITmfTreeDataModel>> response;
                            try (FlowScopeLog iterScope = new FlowScopeLogBuilder(LOGGER, Level.FINE, UPDATE_CONTENT_JOB_NAME + " query") //$NON-NLS-1$
                                    .setParentScope(scope).build()) {

                                response = provider.fetchTree(parameters, monitor);
                                TmfTreeModel<@NonNull ITmfTreeDataModel> model = response.getModel();
                                if (model != null) {
                                    updateTree(trace, start, end, model.getEntries());
                                }
                            }

                            ITmfResponse.Status status = response.getStatus();
                            if (status == ITmfResponse.Status.COMPLETED) {
                                /* Model is complete, no need to request again the data provider */
                                isComplete = true;
                            } else if (status == ITmfResponse.Status.FAILED || status == ITmfResponse.Status.CANCELLED) {
                                /* Error occurred, return */
                                isComplete = true;
                            } else {
                                /**
                                 * Status is RUNNING. Sleeping current thread to wait before request data
                                 * provider again
                                 **/
                                try {
                                    Thread.sleep(BUILD_UPDATE_TIMEOUT);
                                } catch (InterruptedException e) {
                                    /**
                                     * InterruptedException is throw by Thread.Sleep and we should retry querying
                                     * the data provider
                                     **/
                                    runScope.addData(FAILED_TO_SLEEP_PREFIX + getName(), e);
                                    Thread.currentThread().interrupt();
                                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, FAILED_TO_SLEEP_PREFIX + getName());
                                }
                            }
                        } while (!isComplete);

                        return Status.OK_STATUS;
                    }
                }
            };
            thread.setSystem(true);
            thread.schedule();
        }
    }

    private void updateTree(ITmfTrace trace, long start, long end, List<@NonNull ITmfTreeDataModel> model) {
        try (FlowScopeLog parentScope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractSelectTreeViewer:TreeUpdateRequested" ) //$NON-NLS-1$
                .setCategory(fLogCategory).build()) {
            final ITmfTreeViewerEntry rootEntry = modelToTree(start, end, model);
            /* Set the input in main thread only if it didn't change */
            if (rootEntry != null) {
                Display.getDefault().asyncExec(() -> {
                    try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractSelectTreeViewer:TreeUpdate").setParentScope(parentScope).build()) { //$NON-NLS-1$

                        if (!trace.equals(getTrace())) {
                            return;
                        }
                        TreeViewer treeViewer = getTreeViewer();
                        if (treeViewer.getControl().isDisposed()) {
                            return;
                        }
                        Object input = treeViewer.getInput();
                        if (!(input instanceof ITmfTreeViewerEntry) || !treeEquals(rootEntry, (ITmfTreeViewerEntry) input)) {
                            treeViewer.setInput(rootEntry);
                            contentChanged(rootEntry);
                        } else {
                            treeViewer.refresh();
                        }
                        // FIXME should add a bit of padding
                        for (TreeColumn column : treeViewer.getTree().getColumns()) {
                            column.pack();
                        }
                    }
                });
            }
        }
    }

    /**
     * Recursively compare two trees, as the tree viewer requires a fast method,
     * {@link Object#hashCode()} for example.
     *
     * @param entry1
     *            one of the root tree entries to compare
     * @param entry2
     *            the other tree entry to compare
     * @return if the trees are equal
     */
    private boolean treeEquals(ITmfTreeViewerEntry entry1, ITmfTreeViewerEntry entry2) {
        if (!Objects.equals(entry1.getName(), entry2.getName())) {
            return false;
        }
        List<@NonNull ? extends ITmfTreeViewerEntry> children1 = entry1.getChildren();
        List<@NonNull ? extends ITmfTreeViewerEntry> children2 = entry2.getChildren();
        if (children1.size() != children2.size()) {
            return false;
        }
        int size = children1.size();
        for (int i = 0; i < size; i++) {
            if (!treeEquals(children1.get(i), children2.get(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Save the checked entries' ID in the view context before changing trace and
     * check them again in the new tree.
     */
    private void saveViewContext() {
        ITmfTrace previousTrace = getTrace();
        if (previousTrace != null) {
            Object[] checkedElements = fCheckboxTree.getCheckedElements();
            Set<Long> ids = new HashSet<>();
            for (Object checkedElement : checkedElements) {
                if (checkedElement instanceof TmfGenericTreeEntry) {
                    ids.add(((TmfGenericTreeEntry) checkedElement).getModel().getId());
                }
            }
            Text filterControl = fCheckboxTree.getFilterControl();
            String filterString = filterControl != null ? filterControl.getText() : null;
            TmfTraceManager.getInstance().updateTraceContext(previousTrace,
                    builder -> builder.setData(getClass() + CHECKED_ELEMENTS, ids)
                    .setData(getClass() + FILTER_STRING, filterString));
        }
    }

    private void restorePatternFilter(ITmfTrace trace) {
        if (trace == null) {
            fCheckboxTree.getPatternFilter().setPattern(null);
            return;
        }
        TmfTraceContext ctx = TmfTraceManager.getInstance().getTraceContext(trace);
        Object filterString = ctx.getData(getClass() + FILTER_STRING);
        if (filterString instanceof String) {
            fCheckboxTree.getPatternFilter().setPattern((String) filterString);
        } else {
            fCheckboxTree.getPatternFilter().setPattern(null);
        }
    }

    /**
     * Get the legend image for a entry's name
     *
     * @param name
     *            the entry's name (used in both Tree and Chart viewer
     * @return the correctly dimensioned image if there is a legend image provider
     */
    protected Image getLegendImage(@NonNull String name) {
        /* If the image height match the row height, row height will increment */
        ILegendImageProvider legendImageProvider = fLegendImageProvider;
        int legendColumnIndex = fLegendIndex;
        if (legendImageProvider != null && legendColumnIndex >= 0) {
            Tree tree = getTreeViewer().getTree();
            int imageWidth = tree.getColumn(legendColumnIndex).getWidth();
            int imageHeight = tree.getItemHeight() - 1;
            if (imageHeight > 0 && imageWidth > 0) {
                return legendImageProvider.getLegendImage(imageHeight, imageWidth, name);
            }
        }
        return null;
    }

    @Override
    protected ITmfTreeViewerEntry updateElements(ITmfTrace trace, long start, long end, boolean isSelection) {
        throw new UnsupportedOperationException("This method should not be called for AbstractSelectTreeViewers"); //$NON-NLS-1$
    }

    /**
     * Getter for the {@link ITmfTreeDataProvider} to query for this TreeViewer
     *
     * @param trace the trace
     * @return the relevant provider, if any
     * @since 4.0
     */
    protected ITmfTreeDataProvider<@NonNull ITmfTreeDataModel> getProvider(@NonNull ITmfTrace trace) {
        return DataProviderManager.getInstance().getDataProvider(trace, fId, ITmfTreeDataProvider.class);
    }

    @Override
    protected void initializeDataSource(@NonNull ITmfTrace trace) {
        getProvider(trace);
    }

    /**
     * Get the filter to query the {@link ITmfTreeDataProvider} for the queried parameters
     *
     * @param start
     *            query start time
     * @param end
     *            query end time
     * @param isSelection
     *            if the query is a selection
     * @return the resulting query filter
     * @since 4.0
     * @deprecated Use {@link #getParameters(long, long, boolean)} instead
     */
    @Deprecated
    protected @Nullable TimeQueryFilter getFilter(long start, long end, boolean isSelection) {
        return new TimeQueryFilter(Long.min(start, end), Long.max(start, end), 2);
    }

    /**
     * Get the map to query the {@link ITmfTreeDataProvider} for the queried
     * parameters
     *
     * @param start
     *            query start time
     * @param end
     *            query end time
     * @param isSelection
     *            if the query is a selection
     * @return the resulting query parameters
     * @since 5.0
     */
    protected @NonNull Map<String, Object> getParameters(long start, long end, boolean isSelection) {
        return FetchParametersUtils.timeQueryToMap(new TimeQueryFilter(Long.min(start, end), Long.max(start, end), 2));
    }

    /**
     * Algorithm to convert a model (List of {@link TmfTreeDataModel}) to the tree.
     *
     * @param start
     *            queried start time
     * @param end
     *            queried end time
     * @param model
     *            model to convert
     * @return the resulting {@link TmfTreeViewerEntry}.
     */
    protected ITmfTreeViewerEntry modelToTree(long start, long end, List<ITmfTreeDataModel> model) {
        TmfTreeViewerEntry root = new TmfTreeViewerEntry(StringUtils.EMPTY);

        Map<Long, TmfTreeViewerEntry> map = new HashMap<>();
        map.put(-1L, root);
        for (ITmfTreeDataModel entry : model) {
            TmfGenericTreeEntry<ITmfTreeDataModel> viewerEntry = new TmfGenericTreeEntry<>(entry);
            map.put(entry.getId(), viewerEntry);

            TmfTreeViewerEntry parent = map.get(entry.getParentId());
            if (parent != null && !parent.getChildren().contains(viewerEntry)) {
                parent.addChild(viewerEntry);
            }
        }
        return root;
    }

    /**
     * Create a sortable column
     *
     * @param text
     *            column label
     * @param comparator
     *            comparator to sort {@link TmfGenericTreeEntry}s
     * @return the comparator
     */
    protected static <T extends TmfGenericTreeEntry<? extends TmfTreeDataModel>>
    @NonNull TmfTreeColumnData createColumn(String text, Comparator<T> comparator) {
        TmfTreeColumnData column = new TmfTreeColumnData(text);
        column.setComparator(new ViewerComparator() {
            @Override
            public int compare(Viewer viewer, Object e1, Object e2) {
                return comparator.compare((T) e1, (T) e2);
            }
        });
        return column;
    }

    /**
     * Get the full path of the entry, from the trace to itself, to query the
     * presentation provider.
     *
     * @param entry
     *            entry whose legend needs to be resolved.
     * @return the relevant series name.
     */
    protected static @NonNull String getFullPath(TmfGenericTreeEntry<TmfTreeDataModel> entry) {
        StringBuilder path = new StringBuilder(entry.getName());
        ITmfTreeViewerEntry parent = entry.getParent();
        while (parent instanceof TmfGenericTreeEntry) {
            path.insert(0, parent.getName() + '/');
            parent = parent.getParent();
        }
        return path.toString();
    }

    /**
     * Get the checkbox tree in this viewer.
     *
     * @return the checkbox tree.
     * @since 4.0
     */
    public TriStateFilteredCheckboxTree getTriStateFilteredCheckboxTree() {
        return fCheckboxTree;
    }

}
