//=== LoggerAssociation ==================================================

#include "logger/LogAssociation.h"

#include "logger/LogEntry.h"
#include "logger/LogWriter.h"
#include "logger/LoggerRules.h"

/// Constructor
LogAssociation::LogAssociation( LogWriter *writerIn, Rule *ruleIn )
    : writer_( writerIn ),
      rule_( ruleIn ),
      wroteInCycle_( false )
{
    if( NULL != writer_ )
    {
        writer_->addParent();
    }
}

/// Destructor
LogAssociation::~LogAssociation( void )
{
    if( NULL != writer_ )
    {
        writer_->removeParent();
        if( writer_->getParentCount() <= 0 )
        {
            delete writer_;
        }
    }
    if( NULL != rule_ )
    {
        delete rule_;
    }
}

/// Reset cached input settings associated with LogWriter
void LogAssociation::resetInputs()
{
    if( NULL != writer_ )
    {
        writer_->resetInputs();
    }
}

/// Check whether my rules cover a logEntry, write it if applicable
///
/// \param entry The LogEntry to consider
/// \returns true is the LogEntry was processed
bool LogAssociation::matchAndProcess( LogEntry *entry )
{
    if( entry == NULL )
    {
        return false;
    }

    /// Check the entry against this association's rules
    if( NULL != writer_ && writer_->isActive()
            && ( rule_ == NULL
                 || ( rule_->isActive() && rule_->check( entry ) ) ) )
    {
        writer_->write( entry );
        wroteInCycle_ = true;
        return true;
    }

    /// Otherwise, ignore
    return false;
}

/// Do what needs to be done at the end of a cycle.
void LogAssociation::endCycle()
{
    if( wroteInCycle_ )
    {
        wroteInCycle_ = false;
        if( NULL != writer_ )
        {
            writer_->endCycle();
        }
    }
}

/// Call logWriter::writeFooter
void LogAssociation::writeFooter()
{
    if( NULL != writer_ )
    {
        writer_->writeFooter();
    }
}

/// Configure logWriter
void LogAssociation::configLogWriter( Logger& sysLogger )
{
    if( NULL != writer_ )
    {
        writer_->config( sysLogger );
    }
}

//=== LoggerAssociationDeque =============================================
LoggerAssociationDeque::LoggerAssociationDeque( void )
    : FlexArray<LogAssociation * >( true )
{
    ;
}

LoggerAssociationDeque::~LoggerAssociationDeque( void )
{
    //deleteAll();
}

LogAssociation* LoggerAssociationDeque::add( LogWriter *writerIn, Rule *ruleIn )
{
    LogAssociation* logAssociation = new LogAssociation( writerIn, ruleIn );
    add( logAssociation );
    return logAssociation;
}

void LoggerAssociationDeque::add( LogAssociation *association )
{
    push( association );
}

void LoggerAssociationDeque::remove( LogWriter *writerOut )
{
    for( unsigned int i = 0; i < size(); ++i )
    {
        LogAssociation* association = get( i );
        if( NULL != association && association->getWriter() == writerOut )
        {
            pop( i );
            delete association;
            break;
        }
    }
}
