#include "Evaluator.h"
#include "Function.h"
#include "Matcher.h"
#include "VarContext.h"

#include <QDebug>

RuntimeResult::RuntimeResult(QList<Token> result)
{
	_result = result;
}

RuntimeResult::RuntimeResult(QString message)
{
	_errorMessage = message;
	_success = false;
}

bool RuntimeResult::success() const
{
	return _success;
}

QString RuntimeResult::message() const
{
	return _errorMessage;
}

QList<Token> RuntimeResult::result() const
{
	return _result;
}

RuntimeResult::operator QString() const
{
	return QString(_success) + " " + _errorMessage;
}

void Evaluator::addFunction(Function func)
{
	_functions[func.name()] = func;
}

void Evaluator::clearFunction(QString name)
{
	_functions.remove(name);
}

RuntimeResult Evaluator::evaluate(AstNode node, VarContext ctx)
{
	if (node.isSym())
	{
		return RuntimeResult(QList<Token>{Token(node.symbol())});
	}
	else if (node.isIdent())
	{
		return RuntimeResult(QList<Token>{Token(node.name())});
	}
	else if (node.isInteger())
	{
		return RuntimeResult(QList<Token>{Token::fromInteger(node.integer())});
	}
	else if (node.isVar())
	{
		if (!ctx.exists(node.name()) || ctx.exists(node.name()) != node.symbol())
			return RuntimeResult("Variable " + node + " is not defined");

		if (node.symbol() == 'e')
		{
			return RuntimeResult(ctx.expressionVar(node.name()));
		}
		else
		{
			return RuntimeResult(QList<Token>{
					ctx.singleVar(node.name())
				});
		}
	}
	else if (node.isParen())
	{
		QList<Token> result;

		for (const AstNode &n : node.parenContent())
		{
			RuntimeResult internalResult = evaluate(n, ctx);
			if (!internalResult.success())
				return internalResult;

			result.append(internalResult.result());
		}

		return RuntimeResult(QList<Token>{
				Token(result)
			});
	}
	else if (node.isFunc())
	{
		QList<Token> args;

		for (const AstNode &arg : node.funcArgs())
		{
			RuntimeResult internalResult = evaluate(arg, ctx);
			if (!internalResult.success())
				return internalResult;

			args.append(internalResult.result());
		}

		return callFunction(node.name(), args);
	}

	return RuntimeResult("#TYPE_ERROR");
}

RuntimeResult Evaluator::callFunction(QString name, QList<Token> args)
{
	if (!_functions.contains(name))
		return RuntimeResult("Function " + name + " is not defined.");

	Function func = _functions[name];

	for (const Sentence &sentence : func.sentences())
	{
		MatchResult res = match(args, sentence.pattern(), VarContext());

		if (!res.success)
			continue;

		QList<Token> final;
		for (const AstNode &node : sentence.result())
		{
			RuntimeResult argRes = evaluate(node, res.context);
			if (!argRes.success())
				return argRes;

			final.append(argRes.result());
		}

		return RuntimeResult(final);
	}

	return RuntimeResult("Function " + name + " had no matching sentences for input");
}
