/*******************************************************************************
 * Copyright (c) 2016 École Polytechnique de Montréal
 *
 * 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.incubator.internal.xaf.core.statemachine.variable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.backend.BackendStateValue;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.backend.StateMachineBackendAnalysis;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.constraint.Operator;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.constraint.StateMachineConstraint;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.constraint.ValueType;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineNoInvalidCaseException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineNoValidCaseException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineStateSystemNotFoundException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineStateSystemTimeRangeException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineTIDNotFoundException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.exception.StateMachineVariableException;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.StateMachineVariableAnalysis.InterruptionEventRunner;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.InterruptionEvent;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.InterruptionEventList;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.InterruptionReason;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.ResponsibilityMap;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.State;
import org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils.StateMachineVariableHelpers;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineBenchmark;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineInstance;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineInstanceGroup;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineReport;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineUtils;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineInstance.InstanceStepInformation;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineUtils.TimestampInterval;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

/**
 * Class that represents a state machine variable of timer class
 *
 * @author Raphaël Beamonte
 */
public abstract class StateMachineVariableTimer extends StateMachineVariable {

    /**
     * @param name
     *            The name of the variable
     * @param value
     *            The initial value of the variable
     */
    @SuppressWarnings("rawtypes")
    public StateMachineVariableTimer(String name, Comparable value) {
        super(name, value);
    }

    /**
     * @return The attribute of this variable in the backend
     */
    public abstract String getTimerAttribute();

    @Override
    public Comparable getValue(ITmfEvent event, StateMachineInstance stateMachineInstance) throws StateMachineVariableException {
        if (stateMachineInstance.getStateMachineInstanceGroup().getStateMachineBackendAnalysisModules().isEmpty()) {
            throw new StateMachineVariableException("State system unavailable"); //$NON-NLS-1$
        }

        ITmfTimestamp intervalStart = (ITmfTimestamp) getValue();
        ITmfTimestamp intervalEnd = event.getTimestamp();

        int tid = stateMachineInstance.getVTid();
        long usage = 0;
        for (StateMachineBackendAnalysis kernelAnalysisModule : stateMachineInstance.getStateMachineInstanceGroup().getStateMachineBackendAnalysisModules()) {
            Long lusage = kernelAnalysisModule.getTimerIntvl(tid, intervalStart.getValue(), intervalEnd.getValue(), getTimerAttribute());
            if (lusage != null) {
                usage += lusage;
            }
        }

        return usage;
    }

    @Override
    public Integer compareTo(Comparable toCompare, ITmfEvent event, StateMachineInstance stateMachineInstance) throws StateMachineVariableException {
        ITmfTimestamp intervalStart = (ITmfTimestamp) getValue();
        ITmfTimestamp intervalEnd = event.getTimestamp();

        long usage = (long) getValue(event, stateMachineInstance);
        double intvl = intervalEnd.getValue() - intervalStart.getValue();
        Integer comparison = new Double(usage).compareTo(StateMachineUtils.getValueFromPercent((String) toCompare, intvl));

        return comparison;
    }

    @Override
    public Double getNumericalValue(Comparable format, ITmfEvent event, StateMachineInstance stateMachineInstance) {
        try {
            Double delta = ((Long) getValue(event, stateMachineInstance)).doubleValue();

            if (((String) format).endsWith("%")) { //$NON-NLS-1$
                ITmfTimestamp intervalStart = (ITmfTimestamp) getValue();
                ITmfTimestamp intervalEnd = event.getTimestamp();
                double intvl = intervalEnd.getValue() - intervalStart.getValue();
                delta = delta / intvl * 100;
            }

            return delta;
        } catch (StateMachineVariableException e) {
            return null;
        }
    }

    @Override
    public String getFormattedValue(Comparable format, ITmfEvent event, StateMachineInstance stateMachineInstance) {
        Double delta;
        try {
            delta = ((Long) getValue(event, stateMachineInstance)).doubleValue();

            if (((String) format).endsWith("%")) { //$NON-NLS-1$
                ITmfTimestamp intervalStart = (ITmfTimestamp) getValue();
                ITmfTimestamp intervalEnd = event.getTimestamp();
                double intvl = intervalEnd.getValue() - intervalStart.getValue();
                delta = delta / intvl * 100;
            }
        } catch (StateMachineVariableException e) {
            delta = null;
        }

        return getFormattedValue(format, delta);
    }

    @Override
    public String getFormattedValue(Comparable format, Double value) {
        if (value == null) {
            return "unavailable"; //$NON-NLS-1$
        }

        String result = null;

        if (((String) format).endsWith("%")) { //$NON-NLS-1$
            result = String.format("%.4f%%", //$NON-NLS-1$
                    value);
        } else {
            result = String.valueOf(value);
        }
        return result;
    }

    /**
     * Interruption event runner for Timers
     *
     * @author Raphaël Beamonte
     */
    public class DefaultTimerInterruptionEventRunner extends InterruptionEventRunner {
        private final StateMachineVariableTimer variable;
        private final String attribute;
        private Map<ITmfTrace, ITmfContext> contextPerTrace = new HashMap<>();

        /**
         * To create a DefaultTimerInterruptionEventRunner
         *
         * @param variable
         *            The variable for which this interruption event runner will
         *            run
         */
        public DefaultTimerInterruptionEventRunner(StateMachineVariableTimer variable) {
            this.variable = variable;
            this.attribute = variable.getTimerAttribute();
        }

        @Override
        public List<InterruptionEventList> execute(InstanceStepInformation isi) throws StateMachineStateSystemNotFoundException, StateMachineTIDNotFoundException, StateMachineStateSystemTimeRangeException {
            // Get the instance group
            StateMachineInstanceGroup group = isi.instance.getStateMachineInstanceGroup();

            /*
             * If we don't have kernel analysis modules for that group, we can
             * just drop that analysis as we won't have the needed information
             * to analyze that constraint. We can thus return.
             */
            if (group.getStateMachineBackendAnalysisModules().isEmpty()) {
                throw new StateMachineStateSystemNotFoundException();
            }

            /*
             * Thread ID of our instance. We currently only manage situations in
             * which our model follows an unique TID
             */
            Integer tid = isi.instance.getVTid();
            if (tid == null) {
                throw new StateMachineTIDNotFoundException();
            }

            /*
             * Get the timestamp interval for this variable application
             */
            TimestampInterval ti = isi.getVariableInterval(variable.getName());

            /*
             * List in which we will store the events corresponding to an
             * increment of the counter on which that variable is based
             */
            List<InterruptionEventList> interruptionEventList = new ArrayList<>();

            /// USING THE NEW STATE ATTRIBUTE
            boolean analysisDone = false;
            // For each analysis module...
            for (StateMachineBackendAnalysis stateMachineBackendAnalysis : group.getStateMachineBackendAnalysisModules()) {
                ITmfStateSystem ss = stateMachineBackendAnalysis.getStateSystem();
                if (ss == null || ss.getCurrentEndTime() < ti.getEndTime().getValue() || ss.getStartTime() > ti.getStartTime().getValue()) {
                    continue;
                }
                analysisDone = true;

                // Kernel trace on which we're currently working
                ITmfTrace trace = stateMachineBackendAnalysis.getKernelTrace();

                // To store the events we'll read
                ITmfEvent e = null;

                // To store the context for this trace
                ITmfContext ctx = contextPerTrace.get(trace);

                if (ctx != null) {
                    // Get the next event in the trace
                    e = trace.getNext(ctx);

                    // If our event is after our intervalStart... we'll need to
                    // seek :(
                    if (e.getTimestamp().compareTo(ti.getStartTime()) > 0) {
                        ctx.dispose();
                        ctx = null;
                    }
                }

                if (ctx == null) {
                    ctx = trace.seekEvent(ti.getStartTime());
                    contextPerTrace.put(trace, ctx);

                    // Get the initial event of the interval
                    e = trace.getNext(ctx);
                }

                // Can't happen
                if (e == null) {
                    System.out.println("e is null and can't be null... what happened?!"); //$NON-NLS-1$
                    return null;
                }

                // Long value of the interval start timestamp
                long seek = ti.getStartTime().getValue();

                /*
                 * Get the whole interval for which the counter had the same
                 * value as the one it has at seeking time 'seek'
                 */
                StateMachineBenchmark benchmarkObject = new StateMachineBenchmark("Analysis SS Get"); //$NON-NLS-1$
                ITmfStateInterval si = stateMachineBackendAnalysis.getStateInterval(tid, seek, attribute);
                benchmarkObject.stop();

                /*
                 * Change the value of 'seek' to reference the start of the next
                 * value interval for that counter
                 */
                seek = si.getEndTime() + 1;

                /*
                 * If the new value of 'seek' is before the end of the interval,
                 * it means we incremented the counter during that interval, we
                 * thus need to get the event information and store it in our
                 * list. We'll do that as long as our 'seek' value stays before
                 * the end of the interval...
                 */

                IKernelAnalysisEventLayout layout = ((IKernelTrace) e.getTrace()).getKernelEventLayout();
                while (seek < ti.getEndTime().getValue()) {
                    // Loop until we get to the event we're searching
                    while (e.getTimestamp().getValue() < seek
                            || !e.getName().equals(layout.eventSchedSwitch())) {
                        e = trace.getNext(ctx);
                    }

                    /*
                     * Get the whole interval for which the counter had the same
                     * value as the one it has at seeking time 'seek'
                     */
                    benchmarkObject = new StateMachineBenchmark("Analysis SS Get"); //$NON-NLS-1$
                    si = stateMachineBackendAnalysis.getStateInterval(tid, seek, attribute);
                    benchmarkObject.stop();

                    /*
                     * The event should never be 'null'. If it is, show an
                     * error. If not, add it to the list.
                     */
                    if (e.getTimestamp().getValue() > seek) {
                        System.out.println("Didn't find the event at " + seek); //$NON-NLS-1$
                    } else {
                        ITmfEventField content = e.getContent();
                        int tasktid = Integer.parseInt(content.getField(layout.fieldNextTid()).getFormattedValue());

                        // Get the reason of the interruption
                        int state = Integer.parseInt(content.getField(layout.fieldPrevState()).getFormattedValue());

                        InterruptionEventList taskList = new InterruptionEventList();

                        benchmarkObject = new StateMachineBenchmark("Analysis SS Get"); //$NON-NLS-1$
                        ITmfStateInterval si2 = stateMachineBackendAnalysis.getStateInterval(tasktid, seek, attribute);
                        benchmarkObject.stop();

                        while (si2.getStartTime() < si.getEndTime()) {
                            State stateObj = new State(
                                    ((state == 0 || state == 1024) ? BackendStateValue.PREEMPTED : BackendStateValue.BLOCKED).getValue(),
                                    StateMachineVariableHelpers.getSchedSwitchNextProcessInformation(e));
                            taskList.events.add(new InterruptionEvent(
                                    e, TmfTimestamp.create(si2.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE),
                                    stateObj));

                            while (e.getTimestamp().getValue() < si2.getEndTime()
                                    || !e.getName().equals(layout.eventSchedSwitch())) {
                                e = trace.getNext(ctx);
                            }

                            tasktid = Integer.parseInt(e.getContent().getField(layout.fieldNextTid()).getFormattedValue());
                            if (tasktid == tid) {
                                break;
                            }

                            benchmarkObject = new StateMachineBenchmark("Analysis SS Get"); //$NON-NLS-1$
                            si2 = stateMachineBackendAnalysis.getStateInterval(tasktid, si2.getEndTime() + 1, attribute);
                            benchmarkObject.stop();
                        }

                        if (tasktid != tid) {
                            benchmarkObject = new StateMachineBenchmark("Analysis SS Get"); //$NON-NLS-1$
                            taskList.events.add(new InterruptionEvent(e,
                                    TmfTimestamp.create(
                                            si.getEndTime() - stateMachineBackendAnalysis.getTimerIntvl(tid, si.getStartTime(), si.getEndTime(), attribute),
                                            ITmfTimestamp.NANOSECOND_SCALE)));
                            benchmarkObject.stop();
                        }

                        interruptionEventList.add(taskList);
                    }

                    /*
                     * Change the value of seek to be able to seek the next
                     * interval in the next loop
                     */
                    seek = si.getEndTime() + 1;
                }
            }

            // If we couldn't do the analysis
            if (!analysisDone) {
                throw new StateMachineStateSystemTimeRangeException();
            }

            return interruptionEventList;
        }
    }

    /**
     * @return The interruption event runner for that variable
     */
    public InterruptionEventRunner getInterruptionEventRunner() {
        return new DefaultTimerInterruptionEventRunner(this);
    }

    @Override
    public StateMachineVariableAnalysis analyze(StateMachineConstraint constraint, List<InstanceStepInformation> invalidIsiList, List<InstanceStepInformation> validIsiList) {
        // Treat only constants for now
        // TODO: treat comparison between variables
        if (constraint.getValueType() != ValueType.CONSTANT) {
            System.out.println("TODO"); //$NON-NLS-1$
            return null;
        }

        boolean partial = (constraint.getOperator() == Operator.EQ && constraint.getValue().matches("^100 *%$")); //$NON-NLS-1$

        StateMachineVariableAnalysis smva = new StateMachineVariableAnalysis(
                this,
                constraint,
                invalidIsiList,
                validIsiList);

        InterruptionEventRunner interruptionEventRunner = getInterruptionEventRunner();

        StateMachineReport.R.println();
        StateMachineReport.R.println_subsubsubsection(String.format("%s analysis: (%s)", //$NON-NLS-1$
                getVariableType(),
                (partial) ? "partial" : "full")); //$NON-NLS-1$ //$NON-NLS-2$

        if (partial) {
            try {
                smva.doPartialAnalysis(interruptionEventRunner);
            } catch (StateMachineNoInvalidCaseException e) {
                e.printStackTrace();
                return null;
            }
        } else {
            if (validIsiList == null || validIsiList.isEmpty()) {
                System.out.print("No valid instance for a full analysis"); //$NON-NLS-1$
                return null;
            }

            try {
                smva.doAnalysis(interruptionEventRunner);
            } catch (StateMachineNoValidCaseException | StateMachineNoInvalidCaseException e) {
                e.printStackTrace();
                return null;
            }
        }
        StateMachineReport.R.inc();

        StateMachineReport.R.printDropped(smva);

        if (!partial) {
            StateMachineReport.R.println(smva.getDifferentValidCases() +
                    " different valid situation" + (smva.getDifferentValidCases() > 1 ? "s" : "") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                    " for " + validIsiList.size() + //$NON-NLS-1$
                    " different valid case" + (validIsiList.size() > 1 ? "s" : "") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                    "." //$NON-NLS-1$
            );
        }
        StateMachineReport.R.println(smva.getDifferentInvalidCases() +
                " different invalid situation" + (smva.getDifferentInvalidCases() > 1 ? "s" : "") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                " for " + invalidIsiList.size() + //$NON-NLS-1$
                " different invalid case" + (invalidIsiList.size() > 1 ? "s" : "") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                "." //$NON-NLS-1$
        );
        StateMachineReport.R.println();

        ResponsibilityMap<InterruptionReason> analysisResponsibilityMap = smva.getAnalysisResponsibilityMap();

        if (!partial) {
            StateMachineReport.R.println("General computed difference between invalid and valid instances:"); //$NON-NLS-1$
        }
        String[] header = { "Concerning process", "Responsibility" }; //$NON-NLS-1$ //$NON-NLS-2$
        String[][] strs = new String[analysisResponsibilityMap.getCollection().size()][2];
        int idx = 0;
        int progressSize = 20;
        for (Entry<InterruptionReason, Double> entry : analysisResponsibilityMap.getCollection()) {
            double ratioValue = entry.getValue() * 100;
            String symbol = StateMachineReport.progressBar(ratioValue, progressSize);

            strs[idx][0] = entry.getKey().getTaskId();
            strs[idx][1] = String.format("%.2f%% %s", ratioValue, symbol); //$NON-NLS-1$
            idx++;
        }
        StateMachineReport.R.println_table(header, strs, Arrays.asList(new Integer[] { 1 }));
        StateMachineReport.R.println();

        StateMachineReport.R.dec();

        return smva;
    }

    @Override
    public String getVariableType() {
        return this.getClass()
                .getSimpleName()
                .substring(StateMachineVariableTimer.class.getSimpleName().length());
    }

    @Override
    public String toString() {
        return String.format("(%s)%s", //$NON-NLS-1$
                getVariableType(),
                super.toString());
    }

}
