/*******************************************************************************
 * Copyright (c) 2011, 2015 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
 *
 * Contributors:
 *   Marc Dumais - Initial implementation
 *   Francois Chouinard - Misc improvements, DSF signal handling, dynamic experiment
 *   Patrick Tasse - Updated for TMF 2.0
 *   Bernd Hufmann - Fixed deadlock during shutdown
 *******************************************************************************/

package org.eclipse.tracecompass.internal.gdbtrace.core.trace;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.GDBTraceControl_7_2.TraceRecordSelectedChangedEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ITreeModelViewer;
import org.eclipse.debug.ui.AbstractDebugView;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.tracecompass.internal.gdbtrace.core.GdbTraceCorePlugin;
import org.eclipse.tracecompass.internal.gdbtrace.core.event.GdbTraceEvent;
import org.eclipse.tracecompass.internal.gdbtrace.core.event.GdbTraceEventContent;
import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
import org.eclipse.tracecompass.tmf.core.event.TmfEventType;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
import org.eclipse.tracecompass.tmf.ui.editors.ITmfTraceEditor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

/**
 * Adaptor to access GDB Tracepoint frames, previously collected and saved in a
 * file by GDB. One instance of this maps to a single DSF-GDB session.
 * <p>
 * This class offers the functions of starting a post-mortem GDB session with a
 * tracepoint data file, navigate the data frames and return the data contained
 * in a given tracepoint frame.
 * <p>
 * Note: GDB 7.2 or later is required to handle tracepoints
 *
 * @author Marc Dumais
 * @author Francois Chouinard
 */
@SuppressWarnings("restriction")
public class DsfGdbAdaptor {

    private static final Object SESSION_LOCK = new Object();
    private static final String INTERRUPTION_EXCEPTION = "Interruption exception"; //$NON-NLS-1$
    private static final String GDB_EXCEPTION = "GDB exception"; //$NON-NLS-1$
    private static final String REQUEST_REJECTED_EXCEPTION = "Request rejected exception"; //$NON-NLS-1$
    private static final String TIMEOUT = "Timeout"; //$NON-NLS-1$

    private GdbTrace fGdbTrace;

    private int fNumberOfFrames = 0;
    private boolean fIsTimeoutEnabled;
    private int fTimeout;

    private ILaunch fLaunch;
    private boolean isTerminating;
    private DsfSession fDsfSession = null;
    private String fSessionId;

    private String tracedExecutable = ""; //$NON-NLS-1$

    private String gdb72Executable = ""; //$NON-NLS-1$
    private String fTraceFilePath = ""; //$NON-NLS-1$
    private String fTraceFile = ""; //$NON-NLS-1$
    private String sourceLocator = ""; //$NON-NLS-1$

    // To save tracepoints detailed info. The key is the rank of the
    // breakpoint (tracepoint is a kind of breakpoint)
    private Map<Integer, MIBreakpointDMData> fTpInfo = new HashMap<>();

    private TmfEventType tmfEventType = new TmfEventType("GDB Tracepoint", TmfEventField.makeRoot(new String[] { "Content" })); //$NON-NLS-1$ //$NON-NLS-2$

    {
        new DsfGdbPlatformEventListener();
    }

    /**
     * <b><u>DsfGdbPlatformEventListener</u></b>
     * <p>
     * Listens to platform and DSF-GDB events that announce important events
     * about the launchers or a change in debug context that we might need to
     * react-to.
     * <p>
     *
     * @author Francois Chouinard
     */
    private class DsfGdbPlatformEventListener implements
            ILaunchesListener2, IDebugContextListener {

        /**
         *
         */
        public DsfGdbPlatformEventListener() {
            Display.getDefault().syncExec(() -> {
                DebugPlugin.getDefault().getLaunchManager().addLaunchListener(DsfGdbPlatformEventListener.this);
                IWorkbench wb = PlatformUI.getWorkbench();
                IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
                DebugUITools.getDebugContextManager().getContextService(win).addDebugContextListener(DsfGdbPlatformEventListener.this);
            });
        }

        @Override
        public synchronized void launchesRemoved(ILaunch[] launches) {
            // Do nothing
        }

        @Override
        public synchronized void launchesAdded(ILaunch[] launches) {
            // Do nothing
        }

        @Override
        public synchronized void launchesChanged(ILaunch[] launches) {
            // Do nothing
        }

        @Override
        public synchronized void launchesTerminated(ILaunch[] launches) {
            for (ILaunch launch : launches) {
                String sessionId = ((GdbLaunch) launch).getSession().getId();
                closeGdbTraceEditor(sessionId);
            }
        }

        private String fCurrentSessionId = ""; //$NON-NLS-1$
        @Override
        public void debugContextChanged(DebugContextEvent event) {
            ISelection selection = event.getContext();
            if (selection instanceof IStructuredSelection) {
                List<?> eventContextList = ((IStructuredSelection) selection).toList();
                for (Object eventContext : eventContextList) {
                    if (eventContext instanceof IAdaptable) {
                        Object contextObject = ((IAdaptable) eventContext).getAdapter(IDMContext.class);
                        IDMContext context = (IDMContext) contextObject;
                        if (context != null) {
                            String sessionId;
                            synchronized (SESSION_LOCK) {
                                sessionId = context.getSessionId();
                                if (sessionId.equals(fCurrentSessionId)) {
                                    return;
                                }
                                fCurrentSessionId = sessionId;
                            }
                            // Get the current trace record
                            final DsfExecutor executor = DsfSession.getSession(sessionId).getExecutor();
                            final DsfServicesTracker tracker = new DsfServicesTracker(GdbTraceCorePlugin.getBundleContext(), sessionId);
                            Query<ITraceRecordDMContext> getCurrentRecordQuery = new Query<ITraceRecordDMContext>() {
                                @Override
                                public void execute(final DataRequestMonitor<ITraceRecordDMContext> queryRm) {
                                    final IGDBTraceControl traceControl = tracker.getService(IGDBTraceControl.class);
                                    final ICommandControlService commandControl = tracker.getService(ICommandControlService.class);
                                    if (traceControl != null && commandControl != null) {
                                        ITraceTargetDMContext traceContext = (ITraceTargetDMContext) commandControl.getContext();
                                        traceControl.getCurrentTraceRecordContext(traceContext, queryRm);
                                    } else {
                                        queryRm.done();
                                    }
                                }
                            };
                            try {
                                executor.execute(getCurrentRecordQuery);
                                ITraceRecordDMContext record;
                                if (DsfGdbAdaptor.this.fIsTimeoutEnabled) {
                                    record = getCurrentRecordQuery.get(fTimeout, TimeUnit.MILLISECONDS);
                                } else {
                                    record = getCurrentRecordQuery.get();
                                }
                                // If we get a trace record, it means that this can be used
                                if (record != null && record.getRecordId() != null) {
                                    int recordId = Integer.parseInt(record.getRecordId());
                                    selectGdbTraceEditor(sessionId, recordId);
                                    break;
                                }
                            } catch (InterruptedException e) {
                                GdbTraceCorePlugin.logError(INTERRUPTION_EXCEPTION, e);
                                Thread.currentThread().interrupt();
                            } catch (ExecutionException e) {
                                GdbTraceCorePlugin.logError(GDB_EXCEPTION, e);
                            } catch (RejectedExecutionException e) {
                                GdbTraceCorePlugin.logError(REQUEST_REJECTED_EXCEPTION, e);
                            } catch (TimeoutException e) {
                                GdbTraceCorePlugin.logError(TIMEOUT, e);
                            } finally {
                                tracker.dispose();
                            }
                            // else not DSF-GDB or GDB < 7.2
                        }
                    }
                    // else not DSF
                }
            }
        }
    } //  class DsfGdbPlatformEventListener

    /**
     * Constructor for DsfGdbAdaptor.  This is used when we want to launch a
     * DSF-GDB session and use it as source in our tracing perspective.
     * i.e. when launching from the Project Explorer
     *
     * @param trace  the GDB trace
     * @param gdbExec  GDB executable.  Must be version 7.2 or later.
     * @param traceFile  previously generated GDB tracepoint file
     * @param tracedExecutable  executable that was used to generate the tracefile
     *  workspace, where the traced executable was taken from.
     */
    public DsfGdbAdaptor(GdbTrace trace, String gdbExec, String traceFile, String tracedExecutable) {
        this.fGdbTrace = trace;
        this.gdb72Executable = gdbExec;
        this.fTraceFilePath = traceFile;
        this.fTraceFile = traceFile.substring(traceFile.lastIndexOf(IPath.SEPARATOR) + 1);
        this.tracedExecutable = tracedExecutable;

        try {
            launchDGBPostMortemTrace();
        } catch (CoreException e) {
            GdbTraceCorePlugin.logError(e.getMessage(), e);
        }
    }

    /**
     * Builds a launcher and launches a Post-mortem GDB session, based on a
     * previously-gathered GDB Tracepoint file.  The information used to
     * create the launcher is provided to the constructor of this class,
     * at instantiation time.
     * <p>
     * Note: Requires GDB 7.2 or later
     */
    private void launchDGBPostMortemTrace() throws CoreException {
        fIsTimeoutEnabled = Platform.getPreferencesService().getBoolean(GdbPlugin.PLUGIN_ID, IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT, false, null);
        if (fIsTimeoutEnabled) {
            fTimeout = Platform.getPreferencesService().getInt(GdbPlugin.PLUGIN_ID, IGdbDebugPreferenceConstants.PREF_COMMAND_TIMEOUT_VALUE, IGdbDebugPreferenceConstants.COMMAND_TIMEOUT_VALUE_DEFAULT, null);
        }

        ILaunchConfigurationType configType = DebugPlugin
                .getDefault()
                .getLaunchManager()
                .getLaunchConfigurationType("org.eclipse.cdt.launch.postmortemLaunchType"); //$NON-NLS-1$
        ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, fTraceFile);

        wc.setAttribute("org.eclipse.cdt.dsf.gdb.DEBUG_NAME", gdb72Executable); //$NON-NLS-1$
        wc.setAttribute("org.eclipse.cdt.dsf.gdb.POST_MORTEM_TYPE", "TRACE_FILE"); //$NON-NLS-1$ //$NON-NLS-2$
        wc.setAttribute("org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR", 0); //$NON-NLS-1$
        wc.setAttribute("org.eclipse.cdt.launch.COREFILE_PATH", fTraceFilePath); //$NON-NLS-1$
        wc.setAttribute("org.eclipse.cdt.launch.DEBUGGER_START_MODE", "core"); //$NON-NLS-1$ //$NON-NLS-2$
        wc.setAttribute("org.eclipse.cdt.launch.PROGRAM_NAME", tracedExecutable); //$NON-NLS-1$
        // So that the GDB launch is synchronous
        wc.setAttribute("org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND", false); //$NON-NLS-1$

        if (!sourceLocator.isEmpty()) {
            wc.setAttribute("org.eclipse.debug.core.source_locator_memento", sourceLocator); //$NON-NLS-1$
        }

        // Launch GDB session
        fLaunch = wc.doSave().launch("debug", null); //$NON-NLS-1$
        isTerminating = false;

        if (fLaunch instanceof GdbLaunch) {
            fSessionId = ((GdbLaunch) fLaunch).getSession().getId();
        }

        fDsfSession = ((GdbLaunch) fLaunch).getSession();
        fDsfSession.addServiceEventListener(this, null);

        // Find the number of frames contained in the tracepoint file
        fNumberOfFrames = findNumFrames();
    }

    /**
     * This method terminates the current DSF-GDB session
     */
    public void dispose() {
        if (fLaunch != null && fLaunch.canTerminate() && !isTerminating) {
            isTerminating = true;
            try {
                fLaunch.terminate();
            } catch (DebugException e) {
                GdbTraceCorePlugin.logError(e.getMessage(), e);
            }
            fLaunch = null;
        }
    }

    /**
     * This method will try (once per call) to get the number of GDB tracepoint
     * frames for the current session, from DSF-GDB, until it succeeds at
     * getting an amount different than zero.
     *
     * @return The number of frames in current session or zero if unsuccessful
     */
    public int getNumberOfFrames() {
        if (fNumberOfFrames == 0) {
            fNumberOfFrames = findNumFrames();
        }
        return fNumberOfFrames;
    }

    /**
     * Wrapper around the selecting of a frame and the reading of its
     * information. this is a work-around for the potential problem of
     * concurrent access to these functions by more than one thread, where two
     * clients might interfere with each other.
     * <p>
     * Note: We also try to get the tracepoint info here, if it's not already
     * filled-in.
     *
     * @param rank
     *            a long corresponding to the number of the frame to be selected
     *            and read
     * @return A GdbTraceEvent object, or null in case of failure.
     */
    public synchronized GdbTraceEvent selectAndReadFrame(final long rank) {
        // lazy init of tracepoints info
        if (fTpInfo.isEmpty()) {
            getTracepointInfo();
        }
        if (selectDataFrame(rank, false)) {
            GdbTraceEvent event = getTraceFrameData(rank);
            long ts = event.getTimestamp().getValue();
            if (ts == rank) {
                return event;
            }
        }
        return null;
    }

    /**
     * This class implements a best-effort look-up of the detailed tracepoint
     * information (source code filename, line number, etc...).
     */
    private void getTracepointInfo() {

        // Get the latest executor/service tracker
        final DsfExecutor executor = DsfSession.getSession(fSessionId).getExecutor();
        final DsfServicesTracker tracker = new DsfServicesTracker(GdbTraceCorePlugin.getBundleContext(), fSessionId);

        Query<Object> selectRecordQuery = new Query<Object>() {
            @Override
            public void execute(final DataRequestMonitor<Object> drm) {

                // A breakpoint is no longer GDB-global but tied to a specific process
                // So we need to find our process and the ask for its breakpoints
                IMIProcesses procService = tracker.getService(IMIProcesses.class);
                final ICommandControlService cmdControl = tracker.getService(ICommandControlService.class);
                if (procService == null || cmdControl == null) {
                    drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                    drm.done();
                    return;
                }

                ITraceTargetDMContext context = (ITraceTargetDMContext) cmdControl.getContext();
                ICommandControlDMContext cmdControlDMC = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class);

                procService.getProcessesBeingDebugged(
                        cmdControlDMC,
                        new DataRequestMonitor<IDMContext[]>(executor, drm) {
                            @Override
                            protected void handleSuccess() {
                                if (getData() == null || getData().length < 1) {
                                    drm.done();
                                    return;
                                }

                                // Choose the first process for now, until gdb can tell
                                // us which process the trace record is associated with.
                                IContainerDMContext containerDMC = (IContainerDMContext)(getData()[0]);
                                IBreakpointsTargetDMContext bpTargetDMC = DMContexts.getAncestorOfType(containerDMC , IBreakpointsTargetDMContext.class);

                                IMICommandControl commandService = tracker.getService(IMICommandControl.class);
                                if (commandService == null) {
                                    drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                                    drm.done();
                                    return;
                                }

                                CommandFactory cmdFactory = commandService.getCommandFactory();
                                IBreakpoints bpService = tracker.getService(MIBreakpoints.class);
                                if (cmdFactory == null || bpService == null) {
                                    drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                                    drm.done();
                                    return;
                                }

                                // Execute the command
                                cmdControl.queueCommand(cmdFactory.createMIBreakList(bpTargetDMC),
                                        new DataRequestMonitor<MIBreakListInfo>(executor, drm) {
                                    @Override
                                    protected void handleSuccess() {
                                        MIBreakpoint[] breakpoints = getData().getMIBreakpoints();
                                        for (int i = 0; i < breakpoints.length; i++) {
                                            // Use deprecated constructor for Neon backward compatibility
                                            MIBreakpointDMData breakpoint = new MIBreakpointDMData(breakpoints[i]);
                                            String type = breakpoint.getBreakpointType();
                                            // Only save info if the current breakpoint is of type tracepoint
                                            if(type.compareTo(MIBreakpoints.TRACEPOINT) == 0 ) {
                                                fTpInfo.put(Integer.valueOf(breakpoint.getReference()), breakpoint);
                                            }
                                        }
                                        drm.done();
                                    }
                                });
                            }
                        });
            }
        };
        try {
            executor.execute(selectRecordQuery);
            if (fIsTimeoutEnabled) {
                selectRecordQuery.get(fTimeout, TimeUnit.MILLISECONDS); // blocks until time out
            } else {
                selectRecordQuery.get(); // blocks
            }
        } catch (InterruptedException e) {
            GdbTraceCorePlugin.logError(INTERRUPTION_EXCEPTION, e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            GdbTraceCorePlugin.logError(GDB_EXCEPTION, e);
        } catch (RejectedExecutionException e) {
            GdbTraceCorePlugin.logError(REQUEST_REJECTED_EXCEPTION, e);
        } catch (TimeoutException e) {
            GdbTraceCorePlugin.logError(TIMEOUT, e);
        } finally {
            tracker.dispose();
        }
    }

    /**
     * Returns the number of frames contained in currently loaded tracepoint GDB
     * session.
     * <p>
     * Note: A postmortem GDB session must be started before calling
     *         this method
     *
     * @return the number of frames contained in currently loaded tracepoint GDB
     *         session or zero in case of error
     */
    private synchronized int findNumFrames() {
        int frameNum = 0;

        if (DsfSession.getSession(fSessionId) == null) {
            return 0;
        }

        final DsfExecutor executor = DsfSession.getSession(fSessionId)
                .getExecutor();
        final DsfServicesTracker tracker = new DsfServicesTracker(
                GdbTraceCorePlugin.getBundleContext(), fSessionId);

        Query<ITraceStatusDMData> selectRecordQuery = new Query<ITraceStatusDMData>() {
            @Override
            public void execute(
                    final DataRequestMonitor<ITraceStatusDMData> queryRm) {
                final IGDBTraceControl traceControl = tracker
                        .getService(IGDBTraceControl.class);

                final ICommandControlService commandControl = tracker.getService(ICommandControlService.class);
                if (commandControl == null) {
                    queryRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                    queryRm.done();
                    return;
                }
                final ITraceTargetDMContext dmc = (ITraceTargetDMContext) commandControl
                        .getContext();

                if (traceControl != null) {
                    traceControl.getTraceStatus(dmc, queryRm);
                } else {
                    queryRm.done();
                }
            }
        };
        try {
            executor.execute(selectRecordQuery);
            ITraceStatusDMData data;
            if (fIsTimeoutEnabled) {
                data = selectRecordQuery.get(fTimeout, TimeUnit.MILLISECONDS); // blocks until time out
            } else {
                data = selectRecordQuery.get(); // blocks
            }

            frameNum = data.getNumberOfCollectedFrame();
        } catch (InterruptedException e) {
            GdbTraceCorePlugin.logError(INTERRUPTION_EXCEPTION, e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            GdbTraceCorePlugin.logError(GDB_EXCEPTION, e);
        } catch (RejectedExecutionException e) {
            GdbTraceCorePlugin.logError(REQUEST_REJECTED_EXCEPTION, e);
        } catch (TimeoutException e) {
            GdbTraceCorePlugin.logError(TIMEOUT, e);
        } finally {
            tracker.dispose();
        }
        return frameNum;
    }

    /**
     * This method uses the DSF-GDB interface to select a given frame number in
     * the current GDB tracepoint session.
     *
     * @param rank
     *            the rank of the tracepoint frame to select.
     * @param update
     *            true if visualization should be updated
     * @return boolean true if select worked.
     */
    public boolean selectDataFrame(final long rank, final boolean update) {
        boolean status = true;

        final DsfSession dsfSession = DsfSession.getSession(fSessionId);
        if (dsfSession == null) {
            return false;
        }

        if (update) {
            /*
             * Clear the selection to ensure that the new selection is not
             * prevented from overriding the current selection by the DSF
             * selection policy. This could be removed when DSF provides
             * an API to force the trace record selection in the Debug view.
             */
            Display.getDefault().syncExec(() -> {
                for (IWorkbenchWindow wbWindow : PlatformUI.getWorkbench().getWorkbenchWindows()) {
                    for (IWorkbenchPage wbPage : wbWindow.getPages()) {
                        IViewPart vp = wbPage.findView(IDebugUIConstants.ID_DEBUG_VIEW);
                        if (vp instanceof AbstractDebugView) {
                            Viewer viewer = ((AbstractDebugView) vp).getViewer();
                            if (viewer instanceof ITreeModelViewer) {
                                ((ITreeModelViewer) viewer).setSelection(StructuredSelection.EMPTY, false, true);
                            }
                        }
                    }
                }
            });
        }

        final DsfExecutor executor = dsfSession.getExecutor();
        final DsfServicesTracker tracker = new DsfServicesTracker(GdbTraceCorePlugin.getBundleContext(), fSessionId);

        Query<Object> selectRecordQuery = new Query<Object>() {
            @Override
            public void execute(final DataRequestMonitor<Object> queryRm) {
                final IGDBTraceControl traceControl = tracker.getService(IGDBTraceControl.class);

                final ICommandControlService commandControl = tracker.getService(ICommandControlService.class);
                if (commandControl == null) {
                    queryRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                    queryRm.done();
                    return;
                }

                final ITraceTargetDMContext dmc = (ITraceTargetDMContext) commandControl.getContext();

                if (traceControl != null) {
                    ITraceRecordDMContext newCtx = traceControl.createTraceRecordContext(dmc, Integer.toString((int) rank));
                    if (update) {
                        dsfSession.dispatchEvent(new TraceRecordSelectedChangedEvent(newCtx), new Hashtable<String, String>());
                    }
                    traceControl.selectTraceRecord(newCtx, queryRm);
                } else {
                    queryRm.done();
                }
            }
        };
        try {
            executor.execute(selectRecordQuery);
            if (fIsTimeoutEnabled) {
                selectRecordQuery.get(fTimeout, TimeUnit.MILLISECONDS); // blocks until time out
            } else {
                selectRecordQuery.get(); // blocks
            }
        } catch (InterruptedException e) {
            status = false;
            GdbTraceCorePlugin.logError(INTERRUPTION_EXCEPTION, e);
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            status = false;
            GdbTraceCorePlugin.logError(GDB_EXCEPTION, e);
        } catch (RejectedExecutionException e) {
            status = false;
            GdbTraceCorePlugin.logError(REQUEST_REJECTED_EXCEPTION, e);
        } catch (TimeoutException e) {
            status = false;
            GdbTraceCorePlugin.logError(TIMEOUT, e);
        } finally {
            tracker.dispose();
        }
        return status;
    }

    /**
     * This method uses DSF-GDB to read the currently selected GDB tracepoint
     * data frame.   An object of type GdbTraceEvent is build based on the
     * information contained in the data frame and returned to the caller.
     * <p>
     * NOTE : A frame must be selected before calling this method!
     *
     * @param rank  for internal purposes - does <b>not</b> control which
     * frame will be read!
     * @return parsed tp frame, in the form of a GdbTraceEvent
     */
    private GdbTraceEvent getTraceFrameData(final long rank) {

        if (DsfSession.getSession(fSessionId) == null) {
            return null;
        }

        final DsfExecutor executor = DsfSession.getSession(fSessionId).getExecutor();
        final DsfServicesTracker tracker = new DsfServicesTracker(GdbTraceCorePlugin.getBundleContext(), fSessionId);

        Query<ITraceRecordDMData> getFrameDataQuery = new Query<ITraceRecordDMData>() {
            @Override
            public void execute(final DataRequestMonitor<ITraceRecordDMData> rm) {
                final IGDBTraceControl traceControl = tracker.getService(IGDBTraceControl.class);

                final ICommandControlService commandControl = tracker.getService(ICommandControlService.class);
                if (commandControl == null) {
                    rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Could not find necessary services", null)); //$NON-NLS-1$
                    rm.done();
                    return;
                }
                final ITraceTargetDMContext dmc = (ITraceTargetDMContext) commandControl.getContext();

                if (traceControl != null) {
                    traceControl.getCurrentTraceRecordContext(dmc,
                            new DataRequestMonitor<ITraceRecordDMContext>(executor, rm) {
                        @Override
                        protected void handleSuccess() {
                            traceControl.getTraceRecordData(getData(), rm);
                        }
                    });
                } else {
                    rm.done();
                }
            }
        };
        try {
            // Execute the above query
            executor.execute(getFrameDataQuery);
            ITraceRecordDMData data;
            if (fIsTimeoutEnabled) {
                data = getFrameDataQuery.get(fTimeout, TimeUnit.MILLISECONDS); // blocking call until time out
            } else {
                data = getFrameDataQuery.get();
            }

            if (data == null) {
                return null;
            }

            String ts = data.getTimestamp();
            if (ts == null) {
                ts = "0"; //$NON-NLS-1$
            }

            // get corresponding TP data
            String tmfEventRef;
            MIBreakpointDMData bp = fTpInfo.get(Integer.valueOf(data.getTracepointNumber()));
            if (bp != null) {
                tmfEventRef = bp.getFileName() + ":" + bp.getLineNumber() + " :: " + bp.getFunctionName(); //$NON-NLS-1$ //$NON-NLS-2$
            } else {
                tmfEventRef = tracedExecutable;
            }

            GdbTraceEventContent evContent = new GdbTraceEventContent(
                    data.getContent(),
                    Integer.parseInt(data.getTracepointNumber()),
                    Integer.parseInt(data.getRecordId()));

            GdbTraceEvent ev = new GdbTraceEvent(fGdbTrace,
                    TmfTimestamp.fromSeconds(Integer.parseInt(data.getRecordId())),
                    "Tracepoint: " + data.getTracepointNumber() + ", Frame: " + data.getRecordId(),  //$NON-NLS-1$ //$NON-NLS-2$
                    tmfEventType,
                    evContent,
                    tmfEventRef);

            return ev;

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return createExceptionEvent(rank, INTERRUPTION_EXCEPTION);
        } catch (java.util.concurrent.ExecutionException e) {
            return createExceptionEvent(rank, GDB_EXCEPTION);
        } catch (RejectedExecutionException e) {
            return createExceptionEvent(rank, REQUEST_REJECTED_EXCEPTION);
        } catch (TimeoutException e) {
            return createExceptionEvent(rank, TIMEOUT);
        }

        finally {
            tracker.dispose();
        }
    }

    /**
     * This is a helper method for getTraceFrameData, to create for it a
     * "best effort" GdbTraceEvent when a problem occurs during the reading.
     *
     * @param rank
     *            long containing the number of the frame where the problem
     *            occurred
     * @param message
     *            String containing a brief explanation of problem.
     * @return a GdbTraceEvent object, filled as best as possible
     */
    private GdbTraceEvent createExceptionEvent(final long rank, final String message) {
        // get corresponding TP data
        String tmfEventRef;
        String tmfEventSrc;
        MIBreakpointDMData bp = fTpInfo.get((int) rank);
        if (bp != null) {
            tmfEventRef = bp.getFileName() + ":" + bp.getLineNumber() + " :: " + bp.getFunctionName(); //$NON-NLS-1$ //$NON-NLS-2$
            tmfEventSrc = bp.getFileName() + " :: " + bp.getFunctionName() + ", line: " + bp.getLineNumber(); //$NON-NLS-1$ //$NON-NLS-2$
        } else {
            tmfEventRef = tracedExecutable;
            tmfEventSrc = "Tracepoint: n/a"; //$NON-NLS-1$
        }

        GdbTraceEventContent evContent = new GdbTraceEventContent("ERROR: " + message, 0, 0); //$NON-NLS-1$

        GdbTraceEvent ev = new GdbTraceEvent(fGdbTrace,
                TmfTimestamp.fromSeconds(rank),
                tmfEventSrc,
                tmfEventType,
                evContent,
                tmfEventRef);

        return ev;
    }

    /**
     * @return DSF-GDB session id of the current session.
     */
    public String getSessionId() {
        return fSessionId;
    }

    /**
     * Handler method that catches the DSF "record selected changed" event.
     * It in turn creates a TMF "time sync" signal.
     * @param event TraceRecordSelectedChangedEvent:  The DSF event.
     */
    @DsfServiceEventHandler
    public void handleDSFRecordSelectedEvents(final ITraceRecordSelectedChangedDMEvent event) {
        if (event instanceof TraceRecordSelectedChangedEvent) {
            TraceRecordSelectedChangedEvent traceEvent = (TraceRecordSelectedChangedEvent) event;
            ITraceRecordDMContext context = traceEvent.getDMContext();
            final String reference = context.getRecordId();
            if (reference != null) {
                int recordId = Integer.parseInt(reference);
                selectGdbTraceEditor(context.getSessionId(), recordId);
            }
        }
    }

    private static void closeGdbTraceEditor(final String sessionId) {
        Display.getDefault().asyncExec(() -> {
            for (IWorkbenchWindow wbWindow : PlatformUI.getWorkbench().getWorkbenchWindows()) {
                for (IWorkbenchPage wbPage : wbWindow.getPages()) {
                    for (IEditorReference editorReference : wbPage.getEditorReferences()) {
                        IEditorPart editor = editorReference.getEditor(false);
                        if (editor instanceof ITmfTraceEditor) {
                            ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace();
                            if (trace instanceof GdbTrace) {
                                if (((GdbTrace) trace).getDsfSessionId().equals(sessionId)) {
                                    wbPage.closeEditor(editor, false);
                                }
                            }
                        }
                    }
                }
            }
        });
    }

    private static void selectGdbTraceEditor(final String sessionId, final int recordId) {
        Display.getDefault().asyncExec(() -> {
            for (IWorkbenchWindow wbWindow : PlatformUI.getWorkbench().getWorkbenchWindows()) {
                for (IWorkbenchPage wbPage : wbWindow.getPages()) {
                    for (IEditorReference editorReference : wbPage.getEditorReferences()) {
                        IEditorPart editor = editorReference.getEditor(false);
                        if (editor instanceof ITmfTraceEditor) {
                            ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace();
                            if (trace instanceof GdbTrace) {
                                if (((GdbTrace) trace).getDsfSessionId().equals(sessionId)) {
                                    wbPage.bringToTop(editor);
                                    if (recordId != -1) {
                                        gotoRank(editor, recordId);
                                    }
                                    return;
                                }
                            } else if (trace instanceof TmfExperiment) {
                                TmfExperiment experiment = (TmfExperiment) trace;
                                List<ITmfTrace> expTraces = experiment.getTraces();
                                int nbTraces = expTraces.size();
                                for (int i = 0; i < nbTraces; i++) {
                                    GdbTrace gdbTrace = (GdbTrace) expTraces.get(i);
                                    if (gdbTrace.getDsfSessionId().equals(sessionId)) {
                                        wbPage.bringToTop(editor);
                                        if (recordId != -1) {
                                            int rank = recordId * nbTraces + i;
                                            gotoRank(editor, rank);
                                        }
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        });
    }

    private static void gotoRank(IEditorPart editor, int rank) {
        IEditorInput editorInput = editor.getEditorInput();
        if (editorInput instanceof IFileEditorInput) {
            IFile file = ((IFileEditorInput) editorInput).getFile();
            try {
                final IMarker marker = file.createMarker(IMarker.MARKER);
                marker.setAttribute(IMarker.LOCATION, (Integer) rank);
                IDE.gotoMarker(editor, marker);
                marker.delete();
            } catch (CoreException e) {
                GdbTraceCorePlugin.logError(e.getMessage(), e);
            }
        }
    }
}
