/*
 * Copyright (C) 2019 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "IconDatabase.h"

#include "Logging.h"
#include <WebCore/BitmapImage.h>
#include <WebCore/Image.h>
#include <WebCore/SQLiteTransaction.h>
#include <WebCore/SharedBuffer.h>
#include <wtf/FileSystem.h>
#include <wtf/RunLoop.h>
#include <wtf/glib/RunLoopSourcePriority.h>
#include <wtf/threads/BinarySemaphore.h>

namespace WebKit {
using namespace WebCore;

// This version number is in the DB and marks the current generation of the schema
// Currently, a mismatched schema causes the DB to be wiped and reset.
static const int currentDatabaseVersion = 6;

// Icons expire once every 4 days.
static const Seconds iconExpirationTime { 60 * 60 * 24 * 4 };

// We are not interested in icons that have been unused for more than 30 days.
static const Seconds notUsedIconExpirationTime { 60 * 60 * 24 * 30 };

// Loaded icons are cleared after 30 seconds of being requested.
static const Seconds loadedIconExpirationTime { 30_s };

IconDatabase::IconDatabase(const String& path, AllowDatabaseWrite allowDatabaseWrite)
    : m_workQueue(WorkQueue::create("org.webkit.IconDatabase"))
    , m_allowDatabaseWrite(allowDatabaseWrite)
    , m_clearLoadedIconsTimer(RunLoop::main(), this, &IconDatabase::clearLoadedIconsTimerFired)
{
    m_clearLoadedIconsTimer.setPriority(RunLoopSourcePriority::ReleaseUnusedResourcesTimer);

    // We initialize the database synchronously, it's hopefully fast enough because it makes
    // the implementation a lot simpler.
    BinarySemaphore semaphore;
    m_workQueue->dispatch([&] {
        if (allowDatabaseWrite == AllowDatabaseWrite::No && !FileSystem::fileExists(path)) {
            semaphore.signal();
            return;
        }

        auto databaseDirectory = FileSystem::directoryName(path);
        FileSystem::makeAllDirectories(databaseDirectory);
        if (!m_db.open(path)) {
            LOG_ERROR("Unable to open favicon database at path %s - %s", path.utf8().data(), m_db.lastErrorMsg());
            semaphore.signal();
            return;
        }

        auto databaseVersionNumber = SQLiteStatement(m_db, "SELECT value FROM IconDatabaseInfo WHERE key = 'Version';").getColumnInt(0);
        if (databaseVersionNumber > currentDatabaseVersion) {
            LOG(IconDatabase, "Database version number %d is greater than our current version number %d - closing the database to prevent overwriting newer versions",
                databaseVersionNumber, currentDatabaseVersion);
            m_db.close();
            semaphore.signal();
            return;
        }

        if (databaseVersionNumber < currentDatabaseVersion) {
            if (m_allowDatabaseWrite == AllowDatabaseWrite::No) {
                m_db.close();
                semaphore.signal();
                return;
            }

            m_db.clearAllTables();
        }

        // Reduce sqlite RAM cache size from default 2000 pages (~1.5kB per page). 3MB of cache for icon database is overkill.
        SQLiteStatement(m_db, "PRAGMA cache_size = 200;").executeCommand();

        if (allowDatabaseWrite == AllowDatabaseWrite::Yes) {
            m_pruneTimer = makeUnique<RunLoop::Timer<IconDatabase>>(RunLoop::current(), this, &IconDatabase::pruneTimerFired);
            m_pruneTimer->setPriority(RunLoopSourcePriority::ReleaseUnusedResourcesTimer);
        }

        if (!createTablesIfNeeded())
            populatePageURLToIconURLMap();

        semaphore.signal();
    });
    semaphore.wait();
}

IconDatabase::~IconDatabase()
{
    BinarySemaphore semaphore;
    m_workQueue->dispatch([&] {
        if (m_db.isOpen()) {
            m_pruneTimer = nullptr;
            clearStatements();
            m_db.close();
        }
        semaphore.signal();
    });
    semaphore.wait();
}

bool IconDatabase::createTablesIfNeeded()
{
    if (m_db.tableExists("IconInfo") && m_db.tableExists("IconData") && m_db.tableExists("PageURL") && m_db.tableExists("IconDatabaseInfo"))
        return false;

    if (m_allowDatabaseWrite == AllowDatabaseWrite::No) {
        m_db.close();
        return false;
    }

    m_db.clearAllTables();

    if (!m_db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) {
        LOG_ERROR("Could not create PageURL table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE INDEX PageURLIndex ON PageURL (url);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE TABLE IconInfo (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, stamp INTEGER);")) {
        LOG_ERROR("Could not create IconInfo table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE INDEX IconInfoIndex ON IconInfo (url, iconID);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE TABLE IconData (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, data BLOB);")) {
        LOG_ERROR("Could not create IconData table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE INDEX IconDataIndex ON IconData (iconID);")) {
        LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand("CREATE TABLE IconDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
        LOG_ERROR("Could not create IconDatabaseInfo table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }
    if (!m_db.executeCommand(String("INSERT INTO IconDatabaseInfo VALUES ('Version', ") + String::number(currentDatabaseVersion) + ");")) {
        LOG_ERROR("Could not insert icon database version into IconDatabaseInfo table (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
        m_db.close();
        return false;
    }

    return true;
}

void IconDatabase::populatePageURLToIconURLMap()
{
    if (!m_db.isOpen())
        return;

    String importQuery = makeString("SELECT PageURL.url, IconInfo.url, IconInfo.stamp FROM PageURL INNER JOIN IconInfo ON PageURL.iconID=IconInfo.iconID WHERE IconInfo.stamp > ", floor((WallTime::now() - notUsedIconExpirationTime).secondsSinceEpoch().seconds()), ';');
    SQLiteStatement query(m_db, importQuery);
    if (query.prepare() != SQLITE_OK) {
        LOG_ERROR("Unable to prepare icon url import query");
        return;
    }

    auto result = query.step();
    while (result == SQLITE_ROW) {
        m_pageURLToIconURLMap.set(query.getColumnText(0), query.getColumnText(1));
        result = query.step();
    }

    startPruneTimer();
}

void IconDatabase::clearStatements()
{
    RELEASE_ASSERT(m_db.isOpen());

    m_iconIDForIconURLStatement = nullptr;
    m_setIconIDForPageURLStatement = nullptr;
    m_iconDataStatement = nullptr;
    m_addIconStatement = nullptr;
    m_addIconDataStatement = nullptr;
    m_updateIconTimestampStatement = nullptr;
    m_deletePageURLsForIconStatement = nullptr;
    m_deleteIconDataStatement = nullptr;
    m_deleteIconStatement = nullptr;
    m_pruneIconsStatement = nullptr;
}

void IconDatabase::pruneTimerFired()
{
    RELEASE_ASSERT(m_db.isOpen());

    if (!m_pruneIconsStatement) {
        m_pruneIconsStatement = makeUnique<SQLiteStatement>(m_db, "DELETE FROM IconInfo WHERE stamp <= (?);");
        if (m_pruneIconsStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement pruneIcons failed");
            m_pruneIconsStatement = nullptr;
            return;
        }
    }

    if (m_pruneIconsStatement->bindInt64(1, floor((WallTime::now() - notUsedIconExpirationTime).secondsSinceEpoch().seconds())) != SQLITE_OK) {
        LOG_ERROR("FaviconDatabse::pruneTimerFired failed: %s", m_db.lastErrorMsg());
        return;
    }

    SQLiteTransaction transaction(m_db);
    transaction.begin();
    if (m_pruneIconsStatement->step() == SQLITE_DONE) {
        m_db.executeCommand("DELETE FROM IconData WHERE iconID NOT IN (SELECT iconID FROM IconInfo);");
        m_db.executeCommand("DELETE FROM PageURL WHERE iconID NOT IN (SELECT iconID FROM IconInfo);");
    }
    m_pruneIconsStatement->reset();

    transaction.commit();
}

void IconDatabase::startPruneTimer()
{
    if (!m_pruneTimer || !m_db.isOpen())
        return;

    if (m_pruneTimer->isActive())
        m_pruneTimer->stop();
    m_pruneTimer->startOneShot(10_s);
}

void IconDatabase::clearLoadedIconsTimerFired()
{
    auto now = MonotonicTime::now();
    Vector<String> iconsToRemove;
    for (auto iter : m_loadedIcons) {
        if (now - iter.value.second >= loadedIconExpirationTime)
            iconsToRemove.append(iter.key);
    }

    for (auto& iconURL : iconsToRemove)
        m_loadedIcons.remove(iconURL);

    if (!m_loadedIcons.isEmpty())
        startClearLoadedIconsTimer();
}

void IconDatabase::startClearLoadedIconsTimer()
{
    if (m_clearLoadedIconsTimer.isActive())
        return;

    m_clearLoadedIconsTimer.startOneShot(loadedIconExpirationTime);
}

Optional<int64_t> IconDatabase::iconIDForIconURL(const String& iconURL, bool& expired)
{
    RELEASE_ASSERT(m_db.isOpen());

    if (!m_iconIDForIconURLStatement) {
        m_iconIDForIconURLStatement = makeUnique<SQLiteStatement>(m_db, "SELECT IconInfo.iconID, IconInfo.stamp FROM IconInfo WHERE IconInfo.url = (?);");
        if (m_iconIDForIconURLStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement iconIDForIconURL failed");
            m_iconIDForIconURLStatement = nullptr;
            return WTF::nullopt;
        }
    }

    if (m_iconIDForIconURLStatement->bindText(1, iconURL) != SQLITE_OK) {
        LOG_ERROR("FaviconDatabse::iconIDForIconURL failed: %s", m_db.lastErrorMsg());
        return WTF::nullopt;
    }

    Optional<int64_t> result;
    if (m_iconIDForIconURLStatement->step() == SQLITE_ROW) {
        result = m_iconIDForIconURLStatement->getColumnInt64(0);
        expired = m_iconIDForIconURLStatement->getColumnInt64(1) <= floor((WallTime::now() - iconExpirationTime).secondsSinceEpoch().seconds());
    }

    m_iconIDForIconURLStatement->reset();
    return result;
}

bool IconDatabase::setIconIDForPageURL(int64_t iconID, const String& pageURL)
{
    RELEASE_ASSERT(m_db.isOpen());
    RELEASE_ASSERT(m_allowDatabaseWrite == AllowDatabaseWrite::Yes);

    if (!m_setIconIDForPageURLStatement) {
        m_setIconIDForPageURLStatement = makeUnique<SQLiteStatement>(m_db, "INSERT INTO PageURL (url, iconID) VALUES ((?), ?);");
        if (m_setIconIDForPageURLStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement setIconIDForPageURL failed");
            m_setIconIDForPageURLStatement = nullptr;
            return false;
        }
    }

    if (m_setIconIDForPageURLStatement->bindText(1, pageURL) != SQLITE_OK
        || m_setIconIDForPageURLStatement->bindInt64(2, iconID) != SQLITE_OK) {
        LOG_ERROR("FaviconDatabse::setIconIDForPageURL failed: %s", m_db.lastErrorMsg());
        return false;
    }

    if (m_setIconIDForPageURLStatement->step() != SQLITE_DONE)
        ASSERT_NOT_REACHED();

    m_setIconIDForPageURLStatement->reset();
    return true;
}

Vector<char> IconDatabase::iconData(int64_t iconID)
{
    RELEASE_ASSERT(m_db.isOpen());

    if (!m_iconDataStatement) {
        m_iconDataStatement = makeUnique<SQLiteStatement>(m_db, "SELECT IconData.data FROM IconData WHERE IconData.iconID = (?);");
        if (m_iconDataStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement iconData failed");
            m_iconDataStatement = nullptr;
            return { };
        }
    }

    if (m_iconDataStatement->bindInt64(1, iconID) != SQLITE_OK) {
        LOG_ERROR("IconDatabase::iconData failed: %s", m_db.lastErrorMsg());
        return { };
    }

    Vector<char> result;
    if (m_iconDataStatement->step() == SQLITE_ROW)
        m_iconDataStatement->getColumnBlobAsVector(0, result);

    m_iconDataStatement->reset();
    return result;
}

Optional<int64_t> IconDatabase::addIcon(const String& iconURL, const Vector<char>& iconData)
{
    RELEASE_ASSERT(m_db.isOpen());
    RELEASE_ASSERT(m_allowDatabaseWrite == AllowDatabaseWrite::Yes);

    if (!m_addIconStatement) {
        m_addIconStatement = makeUnique<SQLiteStatement>(m_db, "INSERT INTO IconInfo (url, stamp) VALUES (?, 0);");
        if (m_addIconStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement addIcon failed");
            m_addIconStatement = nullptr;
            return WTF::nullopt;
        }
    }
    if (!m_addIconDataStatement) {
        m_addIconDataStatement = makeUnique<SQLiteStatement>(m_db, "INSERT INTO IconData (iconID, data) VALUES (?, ?);");
        if (m_addIconDataStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement addIconData failed");
            m_addIconDataStatement = nullptr;
            return WTF::nullopt;
        }
    }

    if (m_addIconStatement->bindText(1, iconURL) != SQLITE_OK) {
        LOG_ERROR("IconDatabase::addIcon failed: %s", m_db.lastErrorMsg());
        return WTF::nullopt;
    }

    m_addIconStatement->step();
    m_addIconStatement->reset();

    auto iconID = m_db.lastInsertRowID();
    if (m_addIconDataStatement->bindInt64(1, iconID) != SQLITE_OK || m_addIconDataStatement->bindBlob(2, iconData.data(), iconData.size()) != SQLITE_OK) {
        LOG_ERROR("IconDatabase::addIcon failed: %s", m_db.lastErrorMsg());
        return WTF::nullopt;
    }

    m_addIconDataStatement->step();
    m_addIconDataStatement->reset();

    return iconID;
}

void IconDatabase::updateIconTimestamp(int64_t iconID, int64_t timestamp)
{
    RELEASE_ASSERT(m_db.isOpen());
    RELEASE_ASSERT(m_allowDatabaseWrite == AllowDatabaseWrite::Yes);

    if (!m_updateIconTimestampStatement) {
        m_updateIconTimestampStatement = makeUnique<SQLiteStatement>(m_db, "UPDATE IconInfo SET stamp = ? WHERE iconID = ?;");
        if (m_updateIconTimestampStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement updateIconTimestamp failed");
            m_updateIconTimestampStatement = nullptr;
            return;
        }
    }

    if (m_updateIconTimestampStatement->bindInt64(1, timestamp) != SQLITE_OK || m_updateIconTimestampStatement->bindInt64(2, iconID) != SQLITE_OK) {
        LOG_ERROR("IconDatabase::updateIconTimestamp failed: %s", m_db.lastErrorMsg());
        return;
    }

    m_updateIconTimestampStatement->step();
    m_updateIconTimestampStatement->reset();
}

void IconDatabase::deleteIcon(int64_t iconID)
{
    RELEASE_ASSERT(m_db.isOpen());
    RELEASE_ASSERT(m_allowDatabaseWrite == AllowDatabaseWrite::Yes);

    if (!m_deletePageURLsForIconStatement) {
        m_deletePageURLsForIconStatement = makeUnique<SQLiteStatement>(m_db, "DELETE FROM PageURL WHERE PageURL.iconID = (?);");
        if (m_deletePageURLsForIconStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement deletePageURLsForIcon failed");
            m_deletePageURLsForIconStatement = nullptr;
            return;
        }
    }
    if (!m_deleteIconDataStatement) {
        m_deleteIconDataStatement = makeUnique<SQLiteStatement>(m_db, "DELETE FROM IconData WHERE IconData.iconID = (?);");
        if (m_deleteIconDataStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement deleteIcon failed");
            m_deleteIconDataStatement = nullptr;
            return;
        }
    }
    if (!m_deleteIconStatement) {
        m_deleteIconStatement = makeUnique<SQLiteStatement>(m_db, "DELETE FROM IconInfo WHERE IconInfo.iconID = (?);");
        if (m_deleteIconStatement->prepare() != SQLITE_OK) {
            LOG_ERROR("Preparing statement deleteIcon failed");
            m_deleteIconStatement = nullptr;
            return;
        }
    }

    if (m_deletePageURLsForIconStatement->bindInt64(1, iconID) != SQLITE_OK
        || m_deleteIconDataStatement->bindInt64(1, iconID) != SQLITE_OK
        || m_deleteIconStatement->bindInt64(1, iconID) != SQLITE_OK) {
        LOG_ERROR("IconDatabase::deleteIcon failed: %s", m_db.lastErrorMsg());
        return;
    }

    m_deletePageURLsForIconStatement->step();
    m_deleteIconDataStatement->step();
    m_deleteIconStatement->step();

    m_deletePageURLsForIconStatement->reset();
    m_deleteIconDataStatement->reset();
    m_deleteIconStatement->reset();
}

void IconDatabase::checkIconURLAndSetPageURLIfNeeded(const String& iconURL, const String& pageURL, AllowDatabaseWrite allowDatabaseWrite, CompletionHandler<void(bool, bool)>&& completionHandler)
{
    m_workQueue->dispatch([this, protectedThis = makeRef(*this), iconURL = iconURL.isolatedCopy(), pageURL = pageURL.isolatedCopy(), allowDatabaseWrite, completionHandler = WTFMove(completionHandler)]() mutable {
        bool result = false;
        bool changed = false;
        if (m_db.isOpen()) {
            bool canWriteToDatabase = m_allowDatabaseWrite == AllowDatabaseWrite::Yes && allowDatabaseWrite == AllowDatabaseWrite::Yes;
            bool expired = false;
            if (m_pageURLToIconURLMap.get(pageURL) == iconURL)
                result = true;
            else if (auto iconID = iconIDForIconURL(iconURL, expired)) {
                if (expired && canWriteToDatabase) {
                    SQLiteTransaction transaction(m_db);
                    transaction.begin();
                    deleteIcon(iconID.value());
                    transaction.commit();
                } else {
                    result = true;
                    if (!canWriteToDatabase || setIconIDForPageURL(iconID.value(), pageURL)) {
                        m_pageURLToIconURLMap.set(pageURL, iconURL);
                        changed = true;
                    }
                }
            } else if (!canWriteToDatabase && m_loadedIcons.contains(iconURL)) {
                // Found in memory cache.
                result = true;
                m_pageURLToIconURLMap.set(pageURL, iconURL);
                changed = true;
            }
        }
        startPruneTimer();
        RunLoop::main().dispatch([result, changed, completionHandler = WTFMove(completionHandler)]() mutable {
            completionHandler(result, changed);
        });
    });
}

void IconDatabase::loadIconForPageURL(const String& pageURL, AllowDatabaseWrite allowDatabaseWrite, CompletionHandler<void(NativeImagePtr&&)>&& completionHandler)
{
    m_workQueue->dispatch([this, protectedThis = makeRef(*this), pageURL = pageURL.isolatedCopy(), allowDatabaseWrite, timestamp = WallTime::now().secondsSinceEpoch(), completionHandler = WTFMove(completionHandler)]() mutable {
        Optional<int64_t> iconID;
        Vector<char> iconData;
        auto iconURL = m_pageURLToIconURLMap.get(pageURL);
        if (m_db.isOpen() && !iconURL.isEmpty()) {
            bool expired;
            iconID = iconIDForIconURL(iconURL, expired);
            if (iconID && !m_loadedIcons.contains(iconURL)) {
                iconData = this->iconData(iconID.value());
                m_loadedIcons.set(iconURL, std::make_pair<NativeImagePtr, MonotonicTime>(nullptr, { }));
            }
            bool canWriteToDatabase = m_allowDatabaseWrite == AllowDatabaseWrite::Yes && allowDatabaseWrite == AllowDatabaseWrite::Yes;
            if (iconID && canWriteToDatabase)
                updateIconTimestamp(iconID.value(), timestamp.secondsAs<int64_t>());
        }
        startPruneTimer();
        RunLoop::main().dispatch([this, protectedThis = makeRef(*this), iconURL = WTFMove(iconURL), iconData = WTFMove(iconData), completionHandler = WTFMove(completionHandler)]() mutable {
            if (iconURL.isEmpty()) {
                completionHandler(nullptr);
                return;
            }

            auto it = m_loadedIcons.find(iconURL);
            if (it != m_loadedIcons.end() && it->value.first) {
                auto icon = it->value.first;
                it->value.second = MonotonicTime::now();
                startClearLoadedIconsTimer();
                completionHandler(WTFMove(icon));
                return;
            }

            auto addResult = m_loadedIcons.set(iconURL, std::make_pair<NativeImagePtr, MonotonicTime>(nullptr, MonotonicTime::now()));
            if (!iconData.isEmpty()) {
                auto image = BitmapImage::create();
                if (image->setData(SharedBuffer::create(WTFMove(iconData)), true) < EncodedDataStatus::SizeAvailable) {
                    completionHandler(nullptr);
                    return;
                }
                addResult.iterator->value.first = image->nativeImageForCurrentFrame();
            }

            auto icon = addResult.iterator->value.first;
            startClearLoadedIconsTimer();
            completionHandler(WTFMove(icon));
        });
    });
}

String IconDatabase::iconURLForPageURL(const String& pageURL)
{
    return m_pageURLToIconURLMap.get(pageURL);
}

void IconDatabase::setIconForPageURL(const String& iconURL, const unsigned char* iconData, size_t iconDataSize, const String& pageURL, AllowDatabaseWrite allowDatabaseWrite, CompletionHandler<void(bool)>&& completionHandler)
{
    // If database write is not allowed load the icon to cache it in memory only.
    if (m_allowDatabaseWrite == AllowDatabaseWrite::No || allowDatabaseWrite == AllowDatabaseWrite::No) {
        bool result = true;
        auto addResult = m_loadedIcons.set(iconURL, std::make_pair<NativeImagePtr, MonotonicTime>(nullptr, { }));
        if (iconDataSize) {
            auto image = BitmapImage::create();
            if (image->setData(SharedBuffer::create(iconData, iconDataSize), true) < EncodedDataStatus::SizeAvailable)
                result = false;
            else
                addResult.iterator->value.first = image->nativeImageForCurrentFrame();
        }
        startClearLoadedIconsTimer();
        m_workQueue->dispatch([this, protectedThis = makeRef(*this), result, iconURL = iconURL.isolatedCopy(), pageURL = pageURL.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
            m_pageURLToIconURLMap.set(pageURL, iconURL);
            RunLoop::main().dispatch([result, completionHandler = WTFMove(completionHandler)]() mutable {
                completionHandler(result);
            });
        });
        return;
    }

    Vector<char> data;
    data.reserveInitialCapacity(iconDataSize);
    data.append(reinterpret_cast<const char*>(iconData), iconDataSize);
    m_workQueue->dispatch([this, protectedThis = makeRef(*this), iconURL = iconURL.isolatedCopy(), iconData = WTFMove(data), pageURL = pageURL.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
        bool result = false;
        if (m_db.isOpen()) {
            SQLiteTransaction transaction(m_db);
            transaction.begin();

            bool expired = false;
            auto iconID = iconIDForIconURL(iconURL, expired);
            if (!iconID)
                iconID = addIcon(iconURL, iconData);

            if (iconID) {
                result = true;
                if (setIconIDForPageURL(iconID.value(), pageURL))
                    m_pageURLToIconURLMap.set(pageURL, iconURL);
            }

            transaction.commit();
        }
        startPruneTimer();
        RunLoop::main().dispatch([result, completionHandler = WTFMove(completionHandler)]() mutable {
            completionHandler(result);
        });
    });
}

void IconDatabase::clear(CompletionHandler<void()>&& completionHandler)
{
    m_loadedIcons.clear();
    m_workQueue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
        m_pageURLToIconURLMap.clear();

        if (m_db.isOpen() && m_allowDatabaseWrite == AllowDatabaseWrite::Yes) {
            m_pageURLToIconURLMap.clear();

            clearStatements();
            m_db.clearAllTables();
            m_db.runVacuumCommand();
            createTablesIfNeeded();
        }

        RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)]() mutable {
            completionHandler();
        });
    });
}

} // namespace WebKit
