#ifndef SQLLEXER_H
#define SQLLEXER_H

#include <QString>

enum class BasicTokenType {
	None,
	End, // End of input
	Symbol, // can be many things, keyword, object name, operator, ..
	Comment,
	BlockComment,
	OpenBlockComment, // Busy with a block comment end not detected before end of current input
	QuotedString,
	DollarQuote, // Return the dollar quote tag, do not consume the entire string (potentially long)
	QuotedIdentifier,
	Parameter,
	Operator,
	Self, // single char representing it self, maybe remove this and replace with token for each possibility
	Comma,
	Cast,
	WhiteSpace,
	NewLine
};

enum class LexerState {
	Null,
	InDollarQuotedString,
	InBlockComment
};

class SqlToken {
public:
	bool ok;
	int startPos;
	int length;
	BasicTokenType tokenType;
	QString out;
};

class SqlLexer {
public:
	SqlLexer(QString block, LexerState currentstate, bool return_whitespace=false);
	QChar nextChar();
	QChar peekChar();
	/**
	 * @brief NextBasicToken
	 * @param in
	 * @param ofs
	 * @param start
	 * @param length
	 * @return false when input seems invalid, it will return what it did recognize but something wasn't right, parser should try to recover
	 */
	bool nextBasicToken(int &startpos, int &length, BasicTokenType &tokentype, QString &out);
	SqlToken nextBasicToken()
	{
		SqlToken token;
		token.ok = nextBasicToken(token.startPos, token.length, token.tokenType, token.out);
		return token;
	}

	LexerState currentState() const { return m_state; }
private:
	QString m_block;
	int m_pos = 0;
	LexerState m_state;
	bool m_returnWhitespace;

    bool parseSingleQuotedString(int startpos, int &length, BasicTokenType &tokentype);
    bool parseDoubleQuotedIdentifier(int startpos, int &length, BasicTokenType &tokentype);
    bool parseDollarQuote(int startpos, int &length, BasicTokenType &tokentype, QString &out);
};

#endif // SQLLEXER_H
