/*******************************************************************************
 * Copyright (c) 2012, 2016 Ericsson
 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
 *
 * 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:
 *   Alexandre Montplaisir - Initial API and implementation
 *   Patrick Tasse - Add message to exceptions
 *******************************************************************************/

package org.eclipse.tracecompass.internal.statesystem.core;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.log.TraceCompassLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils;
import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;

/**
 * The Transient State is used to build intervals from punctual state changes.
 * It contains a "state info" vector similar to the "current state", except here
 * we also record the start time of every state stored in it.
 *
 * We can then build {@link ITmfStateInterval}'s, to be inserted in a
 * {@link IStateHistoryBackend} when we detect state changes : the "start time"
 * of the interval will be the recorded time we have here, and the "end time"
 * will be the timestamp of the new state-changing event we just read.
 *
 * @author Alexandre Montplaisir
 */
@NonNullByDefault
public class TransientState {

    private static final Logger LOGGER = TraceCompassLog.getLogger(TransientState.class);

    /* Indicates where to insert state changes that we generate */
    private final IStateHistoryBackend fBackend;

    private final ReentrantReadWriteLock fRWLock = new ReentrantReadWriteLock(false);

    private volatile boolean fIsActive;
    private volatile long fLatestTime;

    /* A method accessing these arrays will have to go through the lock */
    private List<@Nullable Object> fOngoingStateInfo;
    private List<Long> fOngoingStateStartTimes;
    private List<@Nullable Class<?>> fStateValueTypes;

    /**
     * Constructor
     *
     * @param backend
     *            The back-end in which to insert the generated state intervals
     */
    public TransientState(IStateHistoryBackend backend) {
        fBackend = backend;
        fIsActive = true;
        fOngoingStateInfo = new ArrayList<>();
        fOngoingStateStartTimes = new ArrayList<>();
        fStateValueTypes = new ArrayList<>();

        fLatestTime = backend.getStartTime();
    }

    /**
     * Get the latest time we have seen so far.
     *
     * @return The latest time seen in the transient state
     */
    public long getLatestTime() {
        return fLatestTime;
    }

    /**
     * Retrieve the ongoing state value for a given index (attribute quark).
     *
     * @param quark
     *            The quark of the attribute to look for
     * @return The corresponding state value
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     */
    public @Nullable Object getOngoingStateValue(int quark) {
        fRWLock.readLock().lock();
        try {
            return fOngoingStateInfo.get(quark);
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Retrieve all the ongoing state values.
     *
     * @return The list of state values
     */
    public List<@Nullable Object> getOngoingStateValues() {
        fRWLock.readLock().lock();
        try {
            return new ArrayList<>(fOngoingStateInfo);
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Retrieve the start time of the state in which the given attribute is in.
     *
     * @param quark
     *            The quark of the attribute to look for
     * @return The start time of the current state for this attribute
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     */
    public long getOngoingStartTime(int quark) {
        fRWLock.readLock().lock();
        try {
            return fOngoingStateStartTimes.get(quark);
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Modify the current state for a given attribute. This will not update the
     * "ongoing state start time" in any way, so be careful when using this.
     *
     * @param quark
     *            The quark of the attribute to modify
     * @param newValue
     *            The state value the attribute should have
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     */
    public void changeOngoingStateValue(int quark, @Nullable Object newValue) {
        fRWLock.writeLock().lock();
        try {
            fOngoingStateInfo.set(quark, newValue);
        } finally {
            fRWLock.writeLock().unlock();
        }
    }

    /**
     * Convenience method to return the "ongoing" value for a given attribute as
     * a dummy interval whose end time = the current latest time.
     *
     * @param quark
     *            The quark of the attribute
     * @return An interval representing the current state (but whose end time is
     *         the current one, and probably not the "final" one)
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     */
    public ITmfStateInterval getOngoingInterval(int quark) {
        fRWLock.readLock().lock();
        try {
            return new TmfStateInterval(fOngoingStateStartTimes.get(quark), fLatestTime,
                    quark, fOngoingStateInfo.get(quark));
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Try to get the state interval valid for time/quark, if it is present in
     * this transient state. If it is not (for example, a new value is active
     * since after the specified timestamp) then null will be returned.
     *
     * @param time
     *            The timestamp to look for
     * @param quark
     *            The quark of the attribute to look for
     * @return The corresponding TmfStateInterval object if we could find it in
     *         this transient state, or null if we couldn't.
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     */
    public @Nullable ITmfStateInterval getIntervalAt(long time, int quark) {
        fRWLock.readLock().lock();
        try {
            if (!isActive() || time < fOngoingStateStartTimes.get(quark)) {
                return null;
            }
            return new TmfStateInterval(fOngoingStateStartTimes.get(quark),
                    fLatestTime, quark, fOngoingStateInfo.get(quark));
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * More advanced version of {@link #changeOngoingStateValue}. Replaces the
     * complete ongoingStateInfo in one go, and updates the
     * ongoingStateStartTimes and #stateValuesTypes accordingly. BE VERY CAREFUL
     * WITH THIS!
     *
     * @param newStateIntervals
     *            The List of intervals that will represent the new
     *            "ongoing state". Their end times don't matter, we will only
     *            check their value and start times.
     */
    public void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
        final int size = newStateIntervals.size();

        fRWLock.writeLock().lock();
        try {
            fOngoingStateInfo = new ArrayList<>(size);
            fOngoingStateStartTimes = new ArrayList<>(size);
            fStateValueTypes = new ArrayList<>(size);

            for (ITmfStateInterval interval : newStateIntervals) {
                Object value = interval.getValue();
                fOngoingStateInfo.add(value);
                fOngoingStateStartTimes.add(interval.getStartTime());
                Class<?> objectClass = value != null ? value.getClass() : null;
                fStateValueTypes.add(objectClass);
            }
        } finally {
            fRWLock.writeLock().unlock();
        }
    }

    /**
     * Add an "empty line" to both "ongoing..." vectors. This is needed so the
     * Ongoing... tables can stay in sync with the number of attributes in the
     * attribute tree, namely when we add sub-path attributes.
     */
    public void addEmptyEntry() {
        fRWLock.writeLock().lock();
        try {
            /*
             * Since this is a new attribute, we suppose it was in the
             * "null state" since the beginning (so we can have intervals
             * covering for all timestamps). A null interval will then get added
             * at the first state change.
             */
            fOngoingStateInfo.add(null);
            fStateValueTypes.add(null);

            fOngoingStateStartTimes.add(fBackend.getStartTime());
        } finally {
            fRWLock.writeLock().unlock();
        }
    }

    /**
     * Process a state change to be inserted in the history.
     *
     * @param eventTime
     *            The timestamp associated with this state change
     * @param value
     *            The new StateValue associated to this attribute
     * @param quark
     *            The quark of the attribute that is being modified
     * @throws TimeRangeException
     *             If 'eventTime' is invalid
     * @throws IndexOutOfBoundsException
     *             If the quark is out of range
     * @throws StateValueTypeException
     *             If the state value to be inserted is of a different type of
     *             what was inserted so far for this attribute.
     */
    public void processStateChange(long eventTime, @Nullable Object value, int quark)
            throws TimeRangeException, StateValueTypeException {
        if (!this.fIsActive) {
            return;
        }

        fRWLock.writeLock().lock();
        try {
            Class<?> expectedSvType = fStateValueTypes.get(quark);

            /*
             * Make sure the state value type we're inserting is the same as the
             * one registered for this attribute.
             */
            if (expectedSvType == null) {
                /*
                 * The value hasn't been used yet, set it to the value we're
                 * currently inserting (which might be null/-1 again).
                 */
                fStateValueTypes.set(quark, value != null ? value.getClass() : null);
            } else if ((value != null) && (value.getClass() != expectedSvType)) {
                /*
                 * We authorize inserting null values in any type of attribute,
                 * but for every other types, it needs to match our
                 * expectations!
                 */
                throw new StateValueTypeException(fBackend.getSSID() + " Quark:" + quark + ", Type:" + value.getClass() + ", Expected:" + expectedSvType); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }

            if (Objects.equals(fOngoingStateInfo.get(quark),value)) {
                /*
                 * This is the case where the new value and the one already
                 * present in the Builder are the same. We do not need to create
                 * an interval, we'll just keep the current one going.
                 */
                return;
            }

            if (fOngoingStateStartTimes.get(quark) < eventTime) {
                /*
                 * These two conditions are necessary to create an interval and
                 * update ongoingStateInfo.
                 */
                fBackend.insertPastState(fOngoingStateStartTimes.get(quark),
                        eventTime - 1, /* End Time */
                        quark, /* attribute quark */
                        fOngoingStateInfo.get(quark)); /* StateValue */

                fOngoingStateStartTimes.set(quark, eventTime);
            }
            fOngoingStateInfo.set(quark, value);

            /* Update the Transient State's lastestTime, if needed */
            if (fLatestTime < eventTime) {
                fLatestTime = eventTime;
            }

        } finally {
            fRWLock.writeLock().unlock();
        }
    }

    /**
     * Run a "get state at time" query on the Transient State only.
     *
     * @param stateInfo
     *            The stateInfo object in which we will put our relevant
     *            information
     * @param t
     *            The requested timestamp
     */
    public void doQuery(List<@Nullable ITmfStateInterval> stateInfo, long t) {
        fRWLock.readLock().lock();
        try {
            if (!this.fIsActive) {
                return;
            }
            if (stateInfo.size() > fOngoingStateInfo.size()) {
                throw new IllegalArgumentException();
            }

            for (int i = 0; i < stateInfo.size(); i++) {
                /*
                 * We build a dummy interval whose end time =
                 * "current transient state end time" to put in the answer to
                 * the query.
                 */
                final ITmfStateInterval interval = getIntervalAt(t, i);
                if (interval != null) {
                    stateInfo.set(i, interval);
                }
            }
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Generalized 2D iterable query method. Iterates over intervals that match
     * the conditions on quarks and times in the Transient State.
     *
     * @param quarks
     *            Collection of quarks for returned intervals.
     * @param timeCondition
     *            Condition on the times for returned intervals
     * @return An iterable over the queried intervals, ordered by quarks.
     * @since 2.1
     */
    public Iterable<ITmfStateInterval> query2D(Collection<Integer> quarks, TimeRangeCondition timeCondition) {
        fRWLock.readLock().lock();
        try (TraceCompassLogUtils.ScopeLog log = new TraceCompassLogUtils.ScopeLog(LOGGER, Level.FINEST, "TransientState:query2D", //$NON-NLS-1$
                "ssid", fBackend.getSSID(), //$NON-NLS-1$
                "quarks", quarks, //$NON-NLS-1$
                "time", timeCondition)) { //$NON-NLS-1$
            if (!fIsActive) {
                return Collections.emptyList();
            }
            long end = timeCondition.max();
            Collection<ITmfStateInterval> iterable = new ArrayList<>();
            for (Integer quark : quarks) {
                ITmfStateInterval interval = getIntervalAt(end, quark);
                if (interval != null) {
                    iterable.add(interval);
                }
            }
            return iterable;
        } finally {
            fRWLock.readLock().unlock();
        }
    }

    /**
     * Close off the Transient State, used for example when we are done reading
     * a static trace file. All the information currently contained in it will
     * be converted to intervals and "flushed" to the state history.
     *
     * @param endTime
     *            The timestamp to use as end time for the state history (since
     *            it may be different than the timestamp of the last state
     *            change)
     */
    public void closeTransientState(long endTime) {
        if (!this.fIsActive) {
            return;
        }

        fRWLock.writeLock().lock();
        try {
            for (int i = 0; i < fOngoingStateInfo.size(); i++) {
                if (fOngoingStateStartTimes.get(i) > endTime) {
                    /*
                     * Handle the cases where trace end > timestamp of last
                     * state change. This can happen when inserting "future"
                     * changes.
                     */
                    continue;
                }
                try {
                    fBackend.insertPastState(fOngoingStateStartTimes.get(i),
                            endTime, /* End Time */
                            i, /* attribute quark */
                            fOngoingStateInfo.get(i)); /* StateValue */

                } catch (TimeRangeException e) {
                    /*
                     * This shouldn't happen, since we control where the
                     * interval's start time comes from
                     */
                    throw new IllegalStateException(e);
                }
            }

            fOngoingStateInfo.clear();
            fOngoingStateStartTimes.clear();
            this.fIsActive = false;

        } finally {
            fRWLock.writeLock().unlock();
        }
    }

    /**
     * Simply returns if this Transient State is currently being used or not
     *
     * @return True if this transient state is active
     */
    public boolean isActive() {
        return this.fIsActive;
    }

    /**
     * Mark this transient state as inactive
     */
    public void setInactive() {
        fIsActive = false;
    }

    /**
     * Debugging method that prints the contents of the transient state
     *
     * @param writer
     *            The writer to which the output should be written
     */
    public void debugPrint(PrintWriter writer) {
        /* Only used for debugging, shouldn't be externalized */
        writer.println("------------------------------"); //$NON-NLS-1$
        writer.println("Info stored in the Builder:"); //$NON-NLS-1$
        if (!this.fIsActive) {
            writer.println("Builder is currently inactive"); //$NON-NLS-1$
            writer.println('\n');
            return;
        }
        writer.println("\nAttribute\tStateValue\tValid since time"); //$NON-NLS-1$
        for (int i = 0; i < fOngoingStateInfo.size(); i++) {
            writer.format("%d\t\t", i); //$NON-NLS-1$
            writer.print(String.valueOf(fOngoingStateInfo.get(i)) + "\t\t"); //$NON-NLS-1$
            writer.println(fOngoingStateStartTimes.get(i).toString());
        }
        writer.println('\n');
        return;
    }

}
