#include <cstdlib>
#include <libwccl/values/bool.h>
#include <libwccl/ops/operator.h>
#include <libwccl/parser/Parser.h>

#include <antlr/NoViableAltException.hpp>
#include <antlr/MismatchedTokenException.hpp>
#include <antlr/TokenStreamRecognitionException.hpp>

// ----------------------------------------------------------------------------

/**
 * @desc It's simple command line tester for testing predicates
 */

int main()
{
	std::string str_in;
	Corpus2::Tagset tagset;
	Wccl::Parser parser(tagset);

	boost::shared_ptr<const Wccl::Value> retVal;
	boost::shared_ptr<Wccl::FunctionalOperator> retOp;
	boost::shared_ptr<Corpus2::Sentence> sentence = boost::make_shared<Corpus2::Sentence>();
	Wccl::SentenceContext sc(sentence);

	Corpus2::Token* the_token = new Corpus2::Token("ZZ", PwrNlp::Whitespace::ManySpaces);
	Corpus2::Tag t1(Corpus2::mask_t(0));
	Corpus2::Lexeme l1("aaa", t1);
	the_token->add_lexeme(l1);
	sentence->append(the_token);

	if (system("clear")) {
		//
	}

	std::cerr << "Simple command line tester for testing bool operators"
						<< std::endl;

	while (1) {
		std::cerr << "Enter a bool operator expression: ";

		getline(std::cin, str_in);

		if (str_in == "clear" || str_in == "cls") {
			if (system("clear")) {
				//
			}
		}
		else if (str_in == "exit" || str_in == "quit") {
			break;
		}
		else {
			try {
				retOp = parser.parseBoolOperator(str_in);

				if (retOp) {
					retVal = retOp->base_apply(sc);

					if(retVal) {
						std::cerr << "Parsed expression: " << retVal->to_raw_string()
								<< std::endl;
					}
					else {
						std::cerr << "Problem while parsing -- Bool is NULL!" << std::endl;
					}
				}
				else {
					std::cerr << "Problem while parsing -- "
							<< "Function<Wccl::Bool> is NULL!" << std::endl;
				}
			}
			catch (antlr::MismatchedTokenException &e) {
				std::cerr << e.getFileLineColumnString()
						<< " " << e.getMessage() << std::endl;
			} catch(antlr::NoViableAltException &e) {
				std::cerr << e.getFileLineColumnString()
						<< " " << e.getMessage() << std::endl;
			} catch(antlr::TokenStreamRecognitionException &e) {
				std::cerr << e.getLine() << ":" << e.getColumn()
						<< " " << e.getMessage() << std::endl;
			} catch (Wccl::InvalidVariableName &e) {
				std::cerr << "Wccl::InvalidVariableName" << std::endl;
			} catch (Wccl::VariableTypeMismatch &e) {
				std::cerr << "Wccl::VariableTypeMismatch" << std::endl;
			} catch (Wccl::InvalidArgument &e) {
				std::cerr << "Wccl::InvalidArgument " << e.info() << std::endl;
			} catch (Wccl::WcclError &e) {
				std::cerr << "Generic WcclError: " << e.info() << std::endl;
			}
			 catch (...) {
				std::cerr << "[N] Syntax error!" << std::endl;
			}
		}
	}

  return 0;
}