/**********************************************************************
 * Copyright (c) 2019 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.swtbot.tests.views;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.TmfContext;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotSwtChart;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer;
import org.eclipse.tracecompass.tmf.ui.views.TmfChartView;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.swtchart.Chart;
import org.swtchart.ISeries;
import org.swtchart.ISeriesSet;

/**
 * Test for XY Chart views in Trace Compass.
 */
@RunWith(SWTBotJunit4ClassRunner.class)
public class XYChartViewTest {

    private static final Logger fLogger = Logger.getRootLogger();

    private SWTBotView fViewBot;

    private TmfTraceStub fTrace;

    private SWTWorkbenchBot fBot;

    private TmfXYChartViewer fXyViewer;

    private static final TmfTimeRange INITIAL_WINDOW_RANGE = new TmfTimeRange(TmfTimestamp.fromNanos(20), TmfTimestamp.fromNanos(100));

    /**
     * Set up for test
     */
    @BeforeClass
    public static void beforeClass() {
        SWTBotUtils.initialize();
        SWTBotPreferences.TIMEOUT = 20000; /* 20 second timeout */
        SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
        fLogger.removeAllAppenders();
        fLogger.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
    }

    /**
     * Before the test is run, make the view see the items.
     *
     * Reset the perspective and close all the views.
     *
     * @throws TmfTraceException
     *             could not load a trace
     */
    @Before
    public void before() throws TmfTraceException {
        fBot = new SWTWorkbenchBot();
        fBot.closeAllEditors();
        for (SWTBotView viewBot : fBot.views()) {
            viewBot.close();
        }
        fTrace = new TmfTraceStub() {

            @Override
            public @NonNull String getName() {
                return "Stub";
            }

            @Override
            public TmfContext seekEvent(ITmfLocation location) {
                return new TmfContext();
            }
        };
        fTrace.setStartTime(TmfTimestamp.fromNanos(0));

        fTrace.setEndTime(TmfTimestamp.fromNanos(180));

        TmfTraceStub trace = fTrace;
        trace.initialize(null, "", ITmfEvent.class);
        assertNotNull(trace);

        // Register trace to trace manager
        UIThreadRunnable.syncExec(() -> TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, trace, null)));

        // Open view
        SWTBotUtils.openView(XYChartViewStub.ID);
        fViewBot = fBot.viewById(XYChartViewStub.ID);
        fViewBot.show();

        TmfChartView viewPart = (TmfChartView) fViewBot.getViewReference().getView(true);
        fXyViewer = viewPart.getChartViewer();

        // Wait till SWT chart is constructed
        fViewBot.bot().waitUntil(new DefaultCondition() {
            @Override
            public boolean test() throws Exception {
                return fXyViewer.getSwtChart() != null;
            }
            @Override
            public String getFailureMessage() {
                return "SWT Chart is null";
            }
        });

        // Wait for trace to be loaded
        resetTimeRange();
    }


    /**
     * Clean up after a test, reset the views.
     */
    @After
    public void after() {
        TmfTraceStub trace = fTrace;
        assertNotNull(trace);
        UIThreadRunnable.syncExec(() -> TmfSignalManager.dispatchSignal(new TmfTraceClosedSignal(this, trace)));
        fViewBot.close();
        fBot.waitUntil(ConditionHelpers.viewIsClosed(fViewBot));
        fTrace.dispose();
    }

    /**
     * Put things back the way they were
     */
    @AfterClass
    public static void afterClass() {
        SWTWorkbenchBot bot = new SWTWorkbenchBot();
        bot.closeAllEditors();
        fLogger.removeAllAppenders();
    }

    /**
     * Test horizontal zoom, we can see a rounding error
     */
    @Test
    public void testHorizontalZoom() {
        fViewBot.setFocus();

        assertEquals(80, fXyViewer.getWindowDuration());

        SWTBotSwtChart xyChart = new SWTBotSwtChart(fViewBot.bot());

        fireKeyInGraph(xyChart, '=');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 52));
        fireKeyInGraph(xyChart, '+');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 34));
        fireKeyInGraph(xyChart, '-');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 51));
        fireKeyInGraph(xyChart, '-');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 77));

        resetTimeRange();

        /* Zoom using zoom-in and zoom-out buttons */
        SWTBotToolbarButton button = fViewBot.toolbarButton("Zoom In");
        button.click();
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 52));
        button = fViewBot.toolbarButton("Zoom Out");
        button.click();
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, 78));

        /*
         *  Note that 'w' and 's' zooming is based on mouse position. Just check if
         *  window range was increased or decreased to avoid inaccuracy due to
         *  the mouse position in test environment.
         */
        long previousRange = fXyViewer.getWindowDuration();
        fireKeyInGraph(xyChart, 'w');
        fViewBot.bot().waitUntil(new SeriesUpdatedCondition(fXyViewer, previousRange, false));
        previousRange = fXyViewer.getWindowDuration();
        fireKeyInGraph(xyChart, 's');
        fViewBot.bot().waitUntil(new SeriesUpdatedCondition(fXyViewer, previousRange, true));
    }

    /**
     * Test zoom to selection
     */
    @Test
    public void testZoomToSelection() {
        SWTBotSwtChart xyChart = new SWTBotSwtChart(fViewBot.bot());

        xyChart.setFocus();

        assertEquals(80, fXyViewer.getWindowDuration());

        /* set selection to trace start time */
        ITmfTimestamp selStartTime = TmfTimestamp.fromNanos(30L);
        ITmfTimestamp selEndTime = TmfTimestamp.fromNanos(80L);
        TmfTimeRange range = new TmfTimeRange(selStartTime, selEndTime);
        TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, selStartTime, selEndTime));
        // Wait till selection is finished
        fViewBot.bot().waitUntil(new DefaultCondition() {
            @Override
            public boolean test() throws Exception {
                return (fXyViewer.getSelectionEndTime() - fXyViewer.getSelectionBeginTime()) == getDuration(range);
            }
            @Override
            public String getFailureMessage() {
                return "SWT Chart is null";
            }
        });
        fireKeyInGraph(xyChart, 'z');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, getDuration(range)));
    }

    /**
     * Test 'a' and 'd' navigation
     */
    @Test
    public void testKeyboardNavigation() {
        SWTBotSwtChart xyChart = new SWTBotSwtChart(fViewBot.bot());
        xyChart.setFocus();
        assertEquals(80, fXyViewer.getWindowDuration());

        TmfTimeRange updatedWindowRange = new TmfTimeRange(TmfTimestamp.fromNanos(40), TmfTimestamp.fromNanos(120));

        // move to the right
        fireKeyInGraph(xyChart, 'd');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, getDuration(updatedWindowRange)));

        // move to the left
        fireKeyInGraph(xyChart, 'a');
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, getDuration(INITIAL_WINDOW_RANGE)));
    }

    // ------------------------------------------------------------------------
    // Helper methods
    // ------------------------------------------------------------------------

    private static void fireKeyInGraph(SWTBotSwtChart chart, char c, int... modifiers) {
        chart.setFocus();
        // Move mouse to middle of the chart
        chart.moveMouseToWidget();
        int mask = 0;
        for (int modifier : modifiers) {
            mask |= modifier;
        }
        chart.pressShortcut(mask, c);
    }

    private static long getDuration(TmfTimeRange range) {
        return range.getEndTime().getValue() - range.getStartTime().getValue();
    }

    private void resetTimeRange() {
        TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, INITIAL_WINDOW_RANGE);
        TmfSignalManager.dispatchSignal(signal);
        fViewBot.bot().waitUntil(new SeriesCondition(fXyViewer, getDuration(INITIAL_WINDOW_RANGE)));
    }

    private static class SeriesCondition extends DefaultCondition {
        private TmfXYChartViewer fViewer;
        private long fExpectedRange;
        private Exception fExecption = null;

        public SeriesCondition(TmfXYChartViewer view, long expectedRange) {
            fViewer = view;
            fExpectedRange = expectedRange;
        }

        @Override
        public boolean test() throws Exception {
            try {
                Chart chart = fViewer.getSwtChart();
                ISeriesSet set = chart.getSeriesSet();
                if (set == null) {
                    return false;
                }
                ISeries[] series = set.getSeries();
                return series != null && series.length > 0 && fExpectedRange == fViewer.getWindowDuration();
            } catch (Exception e) {
                fExecption = e;
                throw e;
            }
        }

        @Override
        public String getFailureMessage() {
            return "Expected window range (" + fExpectedRange + ") not achieved. Actual=" + fViewer.getWindowDuration() + (fExecption == null ? "" : (". Exception: " + fExecption));
        }
    }

    private class SeriesUpdatedCondition extends DefaultCondition {
        TmfXYChartViewer fView;
        long fPreviousRange;
        boolean fIsIncreased;
        private Exception fExecption = null;

        public SeriesUpdatedCondition(TmfXYChartViewer view, long previousRange, boolean increased) {
            fView = view;
            fPreviousRange = previousRange;
            fIsIncreased = increased;
        }

        @Override
        public boolean test() throws Exception {
            try {
                Chart chart = fView.getSwtChart();
                ISeriesSet set = chart.getSeriesSet();
                if (set == null) {
                    return false;
                }
                ISeries[] series = set.getSeries();
                if (series == null) {
                    return false;
                }
                long newRange = fView.getWindowDuration();
                if (fIsIncreased) {
                    return newRange > fPreviousRange;
                }
                return newRange < fPreviousRange;
            } catch (Exception e) {
                fExecption = e;
                throw e;
            }
        }

        @Override
        public String getFailureMessage() {
            return "Window range didn't " + (fIsIncreased ? "increase" : "decrease") +
                    " (previous: " + fPreviousRange + ", actual: " + fView.getWindowDuration() + ")" + (fExecption == null ? "" : (". Exception: " + fExecption));
        }
    }
}
