/*
 * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "WebIconDatabase.h"

#include "DataReference.h"
#include "Logging.h"
#include "WebContext.h"
#include "WebIconDatabaseProxyMessages.h"
#include <WebCore/FileSystem.h>
#include <WebCore/IconDatabase.h>
#include <WebCore/IconDatabaseBase.h>
#include <wtf/text/WTFString.h>

using namespace WebCore;

namespace WebKit {

PassRefPtr<WebIconDatabase> WebIconDatabase::create(WebContext* context)
{
    return adoptRef(new WebIconDatabase(context));
}

WebIconDatabase::~WebIconDatabase()
{
}

WebIconDatabase::WebIconDatabase(WebContext* context)
    : m_webContext(context)
    , m_urlImportCompleted(false)
    , m_databaseCleanupDisabled(false)
{
}

void WebIconDatabase::invalidate()
{
}

void WebIconDatabase::setDatabasePath(const String& path)
{
    if (m_iconDatabaseImpl && m_iconDatabaseImpl->isOpen()) {
        LOG_ERROR("Icon database already has a path and is already open. We don't currently support changing its path and reopening.");
        return;
    }

    m_iconDatabaseImpl =  IconDatabase::create();
    m_iconDatabaseImpl->setClient(this);
    IconDatabase::delayDatabaseCleanup();
    m_databaseCleanupDisabled = true;
    m_iconDatabaseImpl->setEnabled(true);
    if (!m_iconDatabaseImpl->open(directoryName(path), pathGetFileName(path))) {
        LOG_ERROR("Unable to open WebKit2 icon database on disk");
        m_iconDatabaseImpl.clear();
        setGlobalIconDatabase(0);
        IconDatabase::allowDatabaseCleanup();
        m_databaseCleanupDisabled = false;
    }
    setGlobalIconDatabase(m_iconDatabaseImpl.get());
}

void WebIconDatabase::enableDatabaseCleanup()
{
    if (!m_iconDatabaseImpl) {
        LOG_ERROR("Cannot enabled Icon Database cleanup - it hasn't been opened yet.");
        return;
    }

    if (!m_databaseCleanupDisabled) {
        LOG_ERROR("Attempt to enable database cleanup, but it's already enabled.");
        ASSERT_NOT_REACHED();
        return;
    }
    
    IconDatabase::allowDatabaseCleanup();
    m_databaseCleanupDisabled = false;
}

void WebIconDatabase::retainIconForPageURL(const String& pageURL)
{
    if (m_iconDatabaseImpl)
        m_iconDatabaseImpl->retainIconForPageURL(pageURL);
}

void WebIconDatabase::releaseIconForPageURL(const String& pageURL)
{
    if (m_iconDatabaseImpl)
        m_iconDatabaseImpl->releaseIconForPageURL(pageURL);
}

void WebIconDatabase::setIconURLForPageURL(const String& iconURL, const String& pageURL)
{
    LOG(IconDatabase, "WK2 UIProcess setting icon URL %s for page URL %s", iconURL.ascii().data(), pageURL.ascii().data());
    if (m_iconDatabaseImpl)
        m_iconDatabaseImpl->setIconURLForPageURL(iconURL, pageURL);
}

void WebIconDatabase::setIconDataForIconURL(const CoreIPC::DataReference& iconData, const String& iconURL)
{
    LOG(IconDatabase, "WK2 UIProcess setting icon data (%i bytes) for page URL %s", (int)iconData.size(), iconURL.ascii().data());
    if (!m_iconDatabaseImpl)
        return;

    RefPtr<SharedBuffer> buffer = SharedBuffer::create(iconData.data(), iconData.size());
    m_iconDatabaseImpl->setIconDataForIconURL(buffer.release(), iconURL);
}

void WebIconDatabase::synchronousIconDataForPageURL(const String&, CoreIPC::DataReference& iconData)
{
    iconData = CoreIPC::DataReference();
}

void WebIconDatabase::synchronousIconURLForPageURL(const String&, String& iconURL)
{
    iconURL = String();
}

void WebIconDatabase::synchronousIconDataKnownForIconURL(const String&, bool& iconDataKnown) const
{
    iconDataKnown = false;
}

void WebIconDatabase::synchronousLoadDecisionForIconURL(const String&, int& loadDecision) const
{
    loadDecision = static_cast<int>(IconLoadNo);
}

void WebIconDatabase::getLoadDecisionForIconURL(const String& iconURL, uint64_t callbackID)
{
    LOG(IconDatabase, "WK2 UIProcess getting load decision for icon URL %s with callback ID %lli", iconURL.ascii().data(), static_cast<long long>(callbackID));

    if (!m_webContext)
        return;

    if (!m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || iconURL.isEmpty()) {
        // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
        m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(IconLoadNo), callbackID));
        return;
    }
    
    // If the decision hasn't been read from disk yet, set this url and callback ID aside to be notifed later
    IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(iconURL, 0);
    if (decision == IconLoadUnknown) {
        // We should never get an unknown load decision after the URL import has completed.
        ASSERT(!m_urlImportCompleted);
        
        m_pendingLoadDecisionURLMap.set(callbackID, iconURL);
        return;    
    }

    // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
    m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision((int)decision, callbackID));
}

Image* WebIconDatabase::imageForPageURL(const String& pageURL)
{
    if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty())
        return 0;    

    // The WebCore IconDatabase ignores the passed in size parameter.
    // If that changes we'll need to rethink how this API is exposed.
    return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, WebCore::IntSize(32, 32));
}

void WebIconDatabase::removeAllIcons()
{
    m_iconDatabaseImpl->removeAllIcons();   
}

void WebIconDatabase::checkIntegrityBeforeOpening()
{
    IconDatabase::checkIntegrityBeforeOpening();
}

void WebIconDatabase::close()
{
    m_iconDatabaseImpl->close();
}

void WebIconDatabase::initializeIconDatabaseClient(const WKIconDatabaseClient* client)
{
    m_iconDatabaseClient.initialize(client);
}

// WebCore::IconDatabaseClient
bool WebIconDatabase::performImport()
{
    // WebKit2 icon database doesn't currently support importing any old icon database formats.
    return true;
}

void WebIconDatabase::didImportIconURLForPageURL(const String& pageURL)
{
    didChangeIconForPageURL(pageURL);
}

void WebIconDatabase::didImportIconDataForPageURL(const String& pageURL)
{
    didChangeIconForPageURL(pageURL);
}

void WebIconDatabase::didChangeIconForPageURL(const String& pageURL)
{
    m_iconDatabaseClient.didChangeIconForPageURL(this, WebURL::create(pageURL).get());
}

void WebIconDatabase::didRemoveAllIcons()
{
    m_iconDatabaseClient.didRemoveAllIcons(this);
}

void WebIconDatabase::didFinishURLImport()
{
    if (!m_webContext)
        return;
    
    ASSERT(!m_urlImportCompleted);

    LOG(IconDatabase, "WK2 UIProcess URL import complete, notifying all %i pending page URL load decisions", m_pendingLoadDecisionURLMap.size());

    HashMap<uint64_t, String>::iterator i = m_pendingLoadDecisionURLMap.begin();
    HashMap<uint64_t, String>::iterator end = m_pendingLoadDecisionURLMap.end();
    
    for (; i != end; ++i) {
        LOG(IconDatabase, "WK2 UIProcess performing delayed callback on callback ID %i for page url %s", (int)i->first, i->second.ascii().data());
        IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(i->second, 0);

        // Decisions should never be unknown after the inital import is complete
        ASSERT(decision != IconLoadUnknown);

        // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
        m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(decision), i->first));
    }
    
    m_pendingLoadDecisionURLMap.clear();
    
    m_urlImportCompleted = true;
}

void WebIconDatabase::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* decoder)
{
    didReceiveWebIconDatabaseMessage(connection, messageID, decoder);
}

CoreIPC::SyncReplyMode WebIconDatabase::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* decoder, CoreIPC::ArgumentEncoder* reply)
{
    return didReceiveSyncWebIconDatabaseMessage(connection, messageID, decoder, reply);
}

} // namespace WebKit
