/*
 * Author: Radovan Cerveny
 */

#ifndef NONDETERMINISTIC_EXACT_SUFFIX_EPSILON_AUTOMATON_H_
#define NONDETERMINISTIC_EXACT_SUFFIX_EPSILON_AUTOMATON_H_

#include <automaton/FSM/EpsilonNFA.h>
#include <string/LinearString.h>

namespace stringology {

namespace indexing {

class NondeterministicExactSuffixEpsilonAutomaton {
public:
	/**
	 * Nondeterministic construction of nondeterministic suffix automaton for given pattern.
	 * @return nondeterministic suffix automaton for given pattern.
	 */
	template < class SymbolType >
	static automaton::EpsilonNFA < SymbolType, unsigned > construct ( const string::LinearString < SymbolType > & pattern );

};

template < class SymbolType >
automaton::EpsilonNFA < SymbolType, unsigned > NondeterministicExactSuffixEpsilonAutomaton::construct ( const string::LinearString < SymbolType > & pattern ) {
	automaton::EpsilonNFA < SymbolType, unsigned > nfaSuffixAutomaton ( 0 );

	nfaSuffixAutomaton.setInputAlphabet ( pattern.getAlphabet ( ) );

	unsigned i = 0;
	for ( const SymbolType & symbol : pattern.getContent ( ) ) {
		nfaSuffixAutomaton.addState ( ++ i );
		nfaSuffixAutomaton.addTransition ( i - 1, symbol, i );
		nfaSuffixAutomaton.addTransition ( 0, i );
	}

	nfaSuffixAutomaton.addFinalState ( i );

	return nfaSuffixAutomaton;
}

} /* namespace indexing */

} /* namespace stringology */

#endif /* NONDETERMINISTIC_EXACT_SUFFIX_EPSILON_AUTOMATON_H_ */
