/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.

#ifndef Patternist_XsdStateMachine_H
#define Patternist_XsdStateMachine_H

#include <private/qnamepool_p.h>

#include <QtCore/QHash>
#include <QtCore/QSet>
#include <QtCore/QTextStream>

QT_BEGIN_NAMESPACE

class QIODevice;

namespace QPatternist
{
    /**
     * @short A state machine used for evaluation.
     *
     * @ingroup Patternist_schema
     * @author Tobias Koenig <tobias.koenig@nokia.com>
     */
    template <typename TransitionType>
    class XsdStateMachine
    {
        public:
            typedef qint32 StateId;

            /**
             * Describes the type of state.
             */
            enum StateType
            {
                StartState,     ///< The state the machine will start with.
                StartEndState,  ///< The state the machine will start with, can be end state as well.
                InternalState,  ///< Any state that is not start or end state.
                EndState        ///< Any state where the machine is allowed to stop.
            };

            /**
             * Creates a new state machine object.
             */
            XsdStateMachine();

            /**
             * Creates a new state machine object.
             *
             * The name pool to use for accessing object names.
             */
            XsdStateMachine(const NamePool::Ptr &namePool);

            /**
             * Adds a new state of the given @p type to the state machine.
             *
             * @return The id of the new state.
             */
            StateId addState(StateType type);

            /**
             * Adds a new @p transition to the state machine.
             *
             * @param start The start state.
             * @param transition The transition to come from the start to the end state.
             * @param end The end state.
             */
            void addTransition(StateId start, TransitionType transition, StateId end);

            /**
             * Adds a new epsilon @p transition to the state machine.
             *
             * @param start The start state.
             * @param end The end state.
             */
            void addEpsilonTransition(StateId start, StateId end);

            /**
             * Resets the machine to the start state.
             */
            void reset();

            /**
             * Removes all states and transitions from the state machine.
             */
            void clear();

            /**
             * Continues execution of the machine with the given input @p transition.
             *
             * @return @c true if the transition was successful, @c false otherwise.
             */
            bool proceed(TransitionType transition);

            /**
             * Returns the list of transitions that are reachable from the current
             * state.
             */
            QList<TransitionType> possibleTransitions() const;

            /**
             * Continues execution of the machine with the given @p input.
             *
             * @note To use this method, inputEqualsTransition must be implemented
             *       to find the right transition to use.
             *
             * @return @c true if the transition was successful, @c false otherwise.
             */
            template <typename InputType>
            bool proceed(InputType input);

            /**
             * Returns whether the given @p input matches the given @p transition.
             */
            template <typename InputType>
            bool inputEqualsTransition(InputType input, TransitionType transition) const;

            /**
             * Returns whether the machine is in an allowed end state.
             */
            bool inEndState() const;

            /**
             * Returns the last transition that was taken.
             */
            TransitionType lastTransition() const;

            /**
             * Returns the start state of the machine.
             */
            StateId startState() const;

            /**
             * This method should be redefined by template specialization for every
             * concret TransitionType.
             */
            QString transitionTypeToString(TransitionType type) const;

            /**
             * Outputs the state machine in DOT format to the given
             * output @p device.
             */
            bool outputGraph(QIODevice *device, const QString &graphName) const;

            /**
             * Returns a DFA that is equal to the NFA of the state machine.
             */
            XsdStateMachine<TransitionType> toDFA() const;

            /**
             * Returns the information of all states of the state machine.
             */
            QHash<StateId, StateType> states() const;

            /**
             * Returns the information of all transitions of the state machine.
             */
            QHash<StateId, QHash<TransitionType, QVector<StateId> > > transitions() const;

        private:
            /**
             * Returns the DFA state for the given @p nfaStat from the given @p stateTable.
             * If there is no corresponding DFA state yet, a new one is created.
             */
            StateId dfaStateForNfaState(QSet<StateId> nfaState, QList< QPair< QSet<StateId>, StateId> > &stateTable, XsdStateMachine<TransitionType> &dfa) const;

            /**
             * Returns the set of all states that can be reached from the set of @p input states
             * by the epsilon transition.
             *
             * The implementation is inlined in order to workaround a compiler
             * bug on Symbian/winscw.
             */
            QSet<StateId> epsilonClosure(const QSet<StateId> &input) const
            {
                // every state can reach itself by epsilon transition, so include the input states
                // in the result as well
                QSet<StateId> result = input;

                // add the input states to the list of to be processed states
                QList<StateId> workStates = input.values();
                while (!workStates.isEmpty()) { // while there are states to be processed left...

                    // dequeue one state from list
                    const StateId state = workStates.takeFirst();

                    // get the list of states that can be reached by the epsilon transition
                    // from the current 'state'
                    const QVector<StateId> targetStates = m_epsilonTransitions.value(state);
                    for (int i = 0; i < targetStates.count(); ++i) {
                        // if we have this target state not in our result set yet...
                        if (!result.contains(targetStates.at(i))) {
                            // ... add it to the result set
                            result.insert(targetStates.at(i));

                            // add the target state to the list of to be processed states as well,
                            // as we want to have the epsilon transitions not only for the first
                            // level of following states
                            workStates.append(targetStates.at(i));
                        }
                    }
                }

                return result;
            }

            /**
             * Returns the set of all states that can be reached from the set of given @p states
             * by the given @p input.
             *
             * The implementation is inlined in order to workaround a compiler
             * bug on Symbian/winscw.
             */
            QSet<StateId> move(const QSet<StateId> &states, TransitionType input) const
            {
                QSet<StateId> result;

                for (const StateId state : states) {

                    // get the transition table for the current state
                    const QHash<TransitionType, QVector<StateId> > transitions = m_transitions.value(state);

                    // get the target states for the given input
                    const QVector<StateId> targetStates = transitions.value(input);

                    // add all target states to the result
                    for (int i = 0; i < targetStates.size(); ++i)
                        result.insert(targetStates.at(i));
                }

                return result;
            }

            NamePool::Ptr                                             m_namePool;
            QHash<StateId, StateType>                                 m_states;
            QHash<StateId, QHash<TransitionType, QVector<StateId> > > m_transitions;
            QHash<StateId, QVector<StateId> >                         m_epsilonTransitions;
            StateId                                                   m_currentState;
            qint32                                                    m_counter;
            TransitionType                                            m_lastTransition;
    };

    #include "qxsdstatemachine_tpl_p.h"
}

QT_END_NAMESPACE

#endif
