#include "data/Event.h"
#include "datatable/DataTableException.h"
#include "context/EventDefinition.h"
#include "event/Acknowledgement.h"
#include "event/Enrichment.h"
#include "datatable/DataTable.h"
#include "IllegalStateException.h"

Event::Event()
{
    init();
}

Event::Event(const AgString& context, EventDefinitionPtr def, int level,
             DataTablePtr data, int64_t id, AgDatePtr creationtime, PermissionsPtr permissions)
{
    init();
    init_(context, def->getName(), level, data, id);

    this->name = def->getName();
    this->permissions = permissions;

    if (creationtime != NULL) {
        this->creationtime = creationtime;
    }

    if (def->getExpirationPeriod() > 0) {
        boost::posix_time::ptime tt = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(def->getExpirationPeriod());
        setExpirationtime( AgDatePtr(new AgDate( tt )) );
    }
}

Event::Event(const AgString& context, const AgString& name, int level, DataTablePtr data, int64_t id)
{
    init();
    init_(context, name, level, data, id);
}

void Event::init()
{
    instantiationtime = AgDatePtr(new AgDate());
    data = DataTablePtr();
	count = 1;
    listener = 0;
    level = 0;

    setCreationtime( AgDatePtr(new AgDate(AgDate::currentDateTime())));
}

void Event::init_(const AgString & context, const AgString & name, int level, DataTablePtr data, int64_t  id)
{
    this->context = context;
    this->name = name;
    this->level = level;
    this->data = data;
    this->id = id;
}

int64_t Event::getId()
{
    return id;
}

AgDatePtr Event::getInstantiationtime()
{
    return instantiationtime;
}

AgDatePtr Event::getCreationtime()
{
    return creationtime;
}

AgString Event::getContext()
{
    return context;
}

AgString Event::getName()
{
    return name;
}

AgDatePtr Event::getExpirationtime()
{
    return expirationtime;
}

//Not used
DataTablePtr Event::getAcknowledgementsTable()
{
    assert(0);
    return DataTablePtr();
}

//Not used
DataTablePtr Event::getEnrichmentsTable()
{
    assert(0);
    return DataTablePtr();
}

//Not used
void Event::setAcknowledgementsTable(DataTablePtr data)
{
    UNUSED(data);
    assert(0);
}

//Not used
void Event::setEnrichmentsTable(DataTablePtr data)
{
    UNUSED(data);
    assert(0);
}

void Event::addAcknowledgement(AcknowledgementPtr ack)
{
    acknowledgements.push_back(ack);
}

std::list<AcknowledgementPtr> Event::getAcknowledgements()
{
    return this->acknowledgements;
}

void Event::addEnrichment(EnrichmentPtr enrichment)
{
    enrichments.push_back(enrichment);
}

std::list<EnrichmentPtr> Event::getEnrichments()
{
    return enrichments;
}

void Event::setId(int64_t id)
{
    this->id = id;
}

void Event::setCreationtime(AgDatePtr creationtime)
{
    this->creationtime = creationtime;
}

void Event::setName(const AgString& name)
{
    this->name = name;
}

void Event::setContext(const AgString& context)
{
    this->context = context;
}

void Event::setExpirationtime(AgDatePtr expirationtime)
{
    this->expirationtime = expirationtime;
}

void Event::setData(DataTablePtr data)
{
    this->data = data;
}

void Event::setListener(int listener)
{
    this->listener = listener;
}

void Event::setLevel(int level)
{
    this->level = level;
}

void Event::setOriginator(AgObjectPtr originator)
{
    this->originator = originator;
}

DataTablePtr Event::getData()
{
    return data;
}

int Event::getListener()
{
    return listener;
}

int Event::getLevel()
{
    return level;
}

PermissionsPtr Event::getPermissions()
{
    return this->permissions;
}

void Event::setPermissions(PermissionsPtr permissions)
{
    this->permissions = permissions;
}

AgObjectPtr Event::getOriginator()
{
    return originator;
}

int Event::getCount()
{
    return count;
}

void Event::setCount(int count)
{
    this->count = count;
}

AgString Event::getDeduplicationId()
{
    return deduplicationId;
}

void Event::setDeduplicationId(const AgString& deduplicationId)
{
    this->deduplicationId = deduplicationId;
}

Event *Event::clone()
{
    Event* clone = new Event;

    clone->context = context;
    clone->name = name;
    clone->data = DataTablePtr( dynamic_cast<DataTable*>(data->clone()) );
    clone->listener = listener;
    clone->level = level;    
    clone->count = count;
    clone->deduplicationId = deduplicationId;

    for (std::list<AcknowledgementPtr>::iterator it=acknowledgements.begin(); it!=acknowledgements.end(); ++it) {
        clone->acknowledgements.push_back(AcknowledgementPtr(dynamic_cast<Acknowledgement*>( (*it)->clone() )));
    }
    for (std::list<EnrichmentPtr>::iterator it=enrichments.begin(); it!=enrichments.end(); ++it) {
        clone->enrichments.push_back(EnrichmentPtr( new Enrichment(*(*it).get())));
    }

    return clone;
}

bool Event::equals(Event* obj)
{
    if(this == obj)
        return true;

    if(obj == 0)
        return false;   

    if (id != obj->id)
        return false;

    return true;
}

AgString Event::toString()
{
    AgString ss;
    ss = AgString("Event '") + name + "' in context '" + context + "': " + (data != NULL ? data->dataAsString() : "no data") + AgString(", for listener '") + AgString::fromInt(listener) + "'";
    return ss;
}
