#include "binding/AbstractBindingProvider.h"
#include "binding/EvaluationOptions.h"
#include "binding/BindingException.h"
#include "binding/Binding.h"
#include "expression/Expression.h"
#include "device/DisconnectionException.h"
#include "util/ErrorCollector.h"
#include "util/Log.h"
#include "util/MessageFormat.h"
#include "Cres.h"

AbstractBindingProvider::AbstractBindingProvider()
{

}

AbstractBindingProvider::AbstractBindingProvider(ErrorCollectorPtr errorCollector)
{
    this->errorCollector = errorCollector;
}

void AbstractBindingProvider::processExecution(int method, BindingPtr binding, EvaluationOptionsPtr options,
                                               ReferencePtr cause, AgObjectPtr result)
{
    UNUSED(options);

    switch (method)
    {
    case EvaluationOptions::STARTUP:
        if(Log::BINDINGS.isDebugEnabled())
        {
            LOG_BINDINGS_DEBUG("Evaluating '" + binding->getExpression()->toString().toUtf8() + "' on startup and writing result ("
                               + result->toString().toUtf8() + ") into '" + binding->getReference()->toString().toUtf8() + "'");
        }
        break;

    case EvaluationOptions::EVENT:
        if(Log::BINDINGS.isDebugEnabled())
        {
            LOG_BINDINGS_DEBUG("Change of '" + cause->toString().toUtf8() + "' caused evaluation of '"
                               + binding->getExpression()->toString().toUtf8() + "' and writing result (" + result->toString().toUtf8() + ") into '"
                               + binding->getReference()->toString().toUtf8() + "'");
        }
        break;

    case EvaluationOptions::PERIODIC:
        if(Log::BINDINGS.isDebugEnabled())
        {
            LOG_BINDINGS_DEBUG("Periodical evaluation of '" + binding->getExpression()->toString().toUtf8()
                               + "' caused writing result (" + result->toString().toUtf8() + ") into '" + binding->getReference()->toString().toUtf8() + "'");
        }
        break;
    }
}

void AbstractBindingProvider::processError(BindingPtr binding, int /*method*/, ReferencePtr /*cause*/, AggreGateException error)
{
    AgString message = MessageFormat::format(Cres::get()->getString("binBindingError"), binding->toString()) + error.getMessage();

    if (errorCollector != NULL)
    {
        errorCollector->addError(BindingException(message, error.getDetails()));
    }
    else
    {
        if((typeid(error) == typeid(DisconnectionException)))
        {
            LOG_BINDINGS_DEBUG(message.toUtf8());
        }
        else
        {
            LOG_BINDINGS_ERROR(message.toUtf8());
        }
    }
}
