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

#include <QDebug>
#include <QCoreApplication>

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

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

RuntimeResult &RuntimeResult::operator =(const RuntimeResult &other)
{
    _errorMessage = other._errorMessage;
    _success = other._success;
    _result = other._result;

    return *this;
}

RuntimeResult RuntimeResult::operator +(const RuntimeResult &other)
{
    RuntimeResult res;

    if (_success)
    {
        res._success = other._success;
        res._result = _result;
        res._result.append(other._result);
        res._errorMessage = other._errorMessage;
    }
    else
    {
        res = *this;
    }

    return res;
}

RuntimeResult &RuntimeResult::operator +=(const RuntimeResult &other)
{
    *this = *this + other;
    return *this;
}

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

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

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

RuntimeResult::operator QString() const
{
    return _errorMessage + pprint(_result);
}

Evaluator::Evaluator()
{
    Function buryFn("Br");
    buryFn.addNativeSentence("s.Name '=' e.Expr", [this](VarContext args)
    {
        Token name = args.singleVar("Name");
        if (name.type() != Token::IDENT)
            rtError("Invalid argument", "First argument to <Br> must be an identifier, received " + pprint(name));

        bury(name.name(), args.expressionVar("Expr"));

        return QList<Token>();
    });
    addFunction(buryFn);

    Function digFn("Dg");
    digFn.addNativeSentence("s.Name", [this](VarContext args)
    {
        Token name = args.singleVar("Name");
        if (name.type() != Token::IDENT)
            rtError("Invalid argument", "First argument to <Dg> must be an identifier, received " + pprint(name));

        return dig(name.name());
    });
    addFunction(digFn);

    Function copyFn("Cp");
    copyFn.addNativeSentence("s.Name", [this](VarContext args)
    {
        Token name = args.singleVar("Name");
        if (name.type() != Token::IDENT)
            rtError("Invalid argument", "First argument to <Cp> must be an identifier, received " + pprint(name));

        return copy(name.name());
    });
    addFunction(copyFn);

    Function undefFn("Undef");
    undefFn.addNativeSentence("s.Name", [this](VarContext args)
    {
        Token name = args.singleVar("Name");
        if (name.type() != Token::IDENT)
            rtError("Invalid argument", "First argument to <Undef> must be an identifier, received " + pprint(name));

        clearFunction(name.name());

        return QList<Token>();
    });
    addFunction(undefFn);
}

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

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

RuntimeResult Evaluator::evaluate(AstNode node, VarContext ctx, int recursionDepth)
{
    if (recursionDepth > _recursionLimit)
    {
        throw StackOverflowException(node);
    }

	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, recursionDepth + 1);
			if (!internalResult.success())
				return internalResult;

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

        return callFunction(node.name(), args, recursionDepth + 1);
	}

	return RuntimeResult("#TYPE_ERROR");
}

RuntimeResult Evaluator::callFunction(QString name, QList<Token> args, int recursionDepth)
{
	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;

		if (sentence.isExternal())
		{
            return RuntimeResult(sentence.externResult(res));
		}

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

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

		return RuntimeResult(final);
	}

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

void Evaluator::quit()
{
    throw EvalQuitException();
}

void Evaluator::reset()
{
    _vars = {};
    _functions = {};
    _shouldContinue = true;
}

QList<Token> Evaluator::dig(QString name)
{
    if (_vars.contains(name))
    {
        QList<Token> value = _vars[name].pop();

        if (_vars[name].empty())
        {
            _vars.remove(name);
        }

        return value;
    }
    else
    {
        return {};
    }
}

QList<Token> Evaluator::copy(QString name)
{
    if (_vars.contains(name))
    {
        return _vars[name].last();
    }
    else
    {
        return {};
    }
}

void Evaluator::bury(QString name, QList<Token> expression)
{
    if (!_vars.contains(name))
    {
        _vars[name] = QStack<QList<Token>>();
    }

    _vars[name].push(expression);
}

void rtError(QString brief, QString details)
{
    throw AssertionException(brief + "\n" + details);
}

void EvalQuitException::raise() const
{
    throw *this;
}

EvalQuitException *EvalQuitException::clone() const
{
    return new EvalQuitException(*this);
}

StackOverflowException::StackOverflowException(AstNode failedAt)
    : QException()
{
    _failedAt = failedAt;
}

AstNode StackOverflowException::failedAt() const
{
    return _failedAt;
}

void StackOverflowException::raise() const
{
    throw *this;
}

StackOverflowException *StackOverflowException::clone() const
{
    return new StackOverflowException(*this);
}

StackOverflowException::operator QString() const
{
    return "StackOverflowException: at " + pprint(_failedAt);
}

AssertionException::AssertionException(QString message)
    : QException()
{
    _message = message;
}

QString AssertionException::message() const
{
    return _message;
}

void AssertionException::raise() const
{
    throw *this;
}

AssertionException *AssertionException::clone() const
{
    return new AssertionException(*this);
}

AssertionException::operator QString() const
{
    return "AssertionException: " + _message;
}
