#include "alarmEventUtils.h"

///////------AlarmEventDataFilter-----
AlarmEventDataFilter::AlarmEventDataFilter()
{
    reset();
}

void AlarmEventDataFilter::reset()
{
    m_beginTime = QDateTime();
    m_endTime = QDateTime();
    m_station.clear();
    m_bay.clear();
    m_type = -1;
    m_severity.clear();
    m_description.clear();
    m_status = -1;
}

bool AlarmEventDataFilter::isEmpty()
{
    return !m_beginTime.isValid() &&
           !m_endTime.isValid() &&
           m_station.isEmpty() &&
           m_bay.isEmpty() &&
           m_type == -1 &&
           m_severity.isEmpty() &&
           m_description.isEmpty() &&
           m_status == -1;
}

bool AlarmEventDataFilter::matches(const EventData& event)
{
    QDateTime eventTime = QDateTime::fromMSecsSinceEpoch(event.timestamp);
    if(m_beginTime.isValid() && eventTime < m_beginTime)
        return false;
    if(m_endTime.isValid() && eventTime > m_endTime)
        return false;

    if(!m_station.isEmpty() && event.stationName != m_station)
        return false;

    if(!m_bay.isEmpty() && event.bayName != m_bay)
        return false;

    if(m_type != -1 && event.type != m_type)
        return false;

    if(!m_severity.isEmpty() && event.severity != m_severity)
        return false;

    if(!m_description.isEmpty() && event.description != m_description)
        return false;

    // if(m_status != -1 && event.status != m_status)
    //     return false;

    return true;
}

void AlarmEventDataFilter::clear()
{
    reset();
}

QVector<EventData> AlarmEventDataFilter::apply(const QVector<EventData>& events)
{
    if(isEmpty())
        return events;

    QVector<EventData> filteredEvents;
    filteredEvents.reserve(events.size()); //分配好内存，防止后面执行append时造成的多次扩容开销

    for(const EventData& event : events)
    {
        if(matches(event))
            filteredEvents.append(event);
    }

    return filteredEvents; //RVO + QT的隐式共享(QVector)，不用担心开销
}


///////------AlarmEventDataFilter-----
AlarmEventCache::AlarmEventCache()
    : m_maxSize(10000)
{}

void AlarmEventCache::trimToSize()
{
    if(m_events.size() > m_maxSize)
    {
        int removeCount = m_events.size() - m_maxSize;
        for(int i = 0; i < removeCount; ++i)
            m_events.removeFirst();
    }
}

void AlarmEventCache::setMaxSize(int maxSize)
{
    m_maxSize = maxSize;
    trimToSize();
}

void AlarmEventCache::clear()
{
    m_events.clear();
}

void AlarmEventCache::addEvent(const EventData& event)
{
    m_events.append(event);
    trimToSize();
}
