/*
 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"

#include "PluginHalter.h"

#include "HaltablePlugin.h"
#include "PlatformString.h"
#include <wtf/CurrentTime.h>
#include <wtf/Vector.h>

using namespace std;

namespace WebCore {

PluginHalter::PluginHalter(PluginHalterClient* client)
    : m_client(client)
    , m_timer(this, &PluginHalter::timerFired)
    , m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
{
    ASSERT_ARG(client, client);
}

void PluginHalter::didStartPlugin(HaltablePlugin* obj)
{
    ASSERT_ARG(obj, obj);
    ASSERT_ARG(obj, !m_plugins.contains(obj));

    if (!m_client->enabled())
        return;

    double currentTime = WTF::currentTime();

    m_plugins.add(obj, currentTime);

    if (m_plugins.size() == 1)
        m_oldestStartTime = currentTime;

    startTimerIfNecessary();
}

void PluginHalter::didStopPlugin(HaltablePlugin* obj)
{
    if (!m_client->enabled())
        return;

    m_plugins.remove(obj);
}

void PluginHalter::timerFired(Timer<PluginHalter>*)
{
    if (m_plugins.isEmpty())
        return;

    Vector<HaltablePlugin*> plugins;
    copyKeysToVector(m_plugins, plugins);

    // Plug-ins older than this are candidates to be halted.
    double pluginCutOffTime = WTF::currentTime() - m_pluginAllowedRunTime;

    m_oldestStartTime = numeric_limits<double>::max();

    for (size_t i = 0; i < plugins.size(); ++i) {
        double thisStartTime = m_plugins.get(plugins[i]);
        if (thisStartTime > pluginCutOffTime) {
            // This plug-in is too young to be halted. We find the oldest
            // plug-in that is not old enough to be halted and use it to set
            // the timer's next fire time.
            if (thisStartTime < m_oldestStartTime)
                m_oldestStartTime = thisStartTime;
            continue;
        }

        if (m_client->shouldHaltPlugin(plugins[i]->node(), plugins[i]->isWindowed(), plugins[i]->pluginName()))
            plugins[i]->halt();

        m_plugins.remove(plugins[i]);
    }

    startTimerIfNecessary();
}

void PluginHalter::startTimerIfNecessary()
{
    if (m_timer.isActive())
        return;

    if (m_plugins.isEmpty())
        return;

    double nextFireInterval = static_cast<double>(m_pluginAllowedRunTime) - (currentTime() - m_oldestStartTime);
    m_timer.startOneShot(nextFireInterval < 0 ? 0 : nextFireInterval);
}

} // namespace WebCore
