/*
 * Copyright (C) 2018 Sony Interactive Entertainment Inc.
 *
 * 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 "SearchPopupMenuDB.h"

#include "SQLiteFileSystem.h"
#include "SQLiteTransaction.h"
#include <wtf/FileSystem.h>
#include <wtf/Vector.h>
#include <wtf/text/StringConcatenateNumbers.h>

namespace WebCore {

static const int schemaVersion = 1;
static constexpr auto createSearchTableSQL {
    "CREATE TABLE IF NOT EXISTS Search ("
    "    name TEXT NOT NULL,"
    "    position INTEGER NOT NULL,"
    "    value TEXT,"
    "    UNIQUE(name, position)"
    ");"_s
};
static constexpr auto loadSearchTermsForNameSQL {
    "SELECT value FROM Search "
    "WHERE name = ? "
    "ORDER BY position;"_s
};
static constexpr auto insertSearchTermSQL {
    "INSERT INTO Search(name, position, value) "
    "VALUES(?, ?, ?);"_s
};
static constexpr auto removeSearchTermsForNameSQL {
    "DELETE FROM Search where name = ?;"_s
};

SearchPopupMenuDB& SearchPopupMenuDB::singleton()
{
    static SearchPopupMenuDB instance;
    return instance;
}

SearchPopupMenuDB::SearchPopupMenuDB()
    : m_databaseFilename(FileSystem::pathByAppendingComponent(FileSystem::localUserSpecificStorageDirectory(), "autosave-search.db"))
{
}

SearchPopupMenuDB::~SearchPopupMenuDB()
{
    closeDatabase();
}

void SearchPopupMenuDB::saveRecentSearches(const String& name, const Vector<RecentSearch>& searches)
{
    if (!m_database.isOpen()) {
        if (!openDatabase())
            return;
    }

    bool success = true;

    SQLiteTransaction transaction(m_database, false);

    m_removeSearchTermsForNameStatement->bindText(1, name);
    auto stepRet = m_removeSearchTermsForNameStatement->step();
    success = stepRet == SQLITE_DONE;
    m_removeSearchTermsForNameStatement->reset();

    int index = 0;
    for (const auto& search : searches) {
        m_insertSearchTermStatement->bindText(1, name);
        m_insertSearchTermStatement->bindInt(2, index);
        m_insertSearchTermStatement->bindText(3, search.string);
        if (success) {
            stepRet = m_insertSearchTermStatement->step();
            success = stepRet == SQLITE_DONE;
        }
        m_insertSearchTermStatement->reset();
        index++;
    }

    if (success)
        transaction.commit();
    checkSQLiteReturnCode(stepRet);
}

void SearchPopupMenuDB::loadRecentSearches(const String& name, Vector<RecentSearch>& searches)
{
    if (!m_database.isOpen()) {
        if (!openDatabase())
            return;
    }

    searches.clear();

    m_loadSearchTermsForNameStatement->bindText(1, name);
    while (m_loadSearchTermsForNameStatement->step() == SQLITE_ROW) {
        // We are choosing not to use or store search times on Windows at this time, so for now it's OK to use a "distant past" time as a placeholder.
        searches.append({ m_loadSearchTermsForNameStatement->getColumnText(0), -WallTime::infinity() });
    }
    m_loadSearchTermsForNameStatement->reset();
}


bool SearchPopupMenuDB::checkDatabaseValidity()
{
    ASSERT(m_database.isOpen());

    if (!m_database.tableExists("Search"))
        return false;

    SQLiteStatement integrity(m_database, "PRAGMA quick_check;");
    if (integrity.prepare() != SQLITE_OK) {
        LOG_ERROR("Failed to execute database integrity check");
        return false;
    }

    int resultCode = integrity.step();
    if (resultCode != SQLITE_ROW) {
        LOG_ERROR("Integrity quick_check step returned %d", resultCode);
        return false;
    }

    int columns = integrity.columnCount();
    if (columns != 1) {
        LOG_ERROR("Received %i columns performing integrity check, should be 1", columns);
        return false;
    }

    String resultText = integrity.getColumnText(0);

    if (resultText != "ok") {
        LOG_ERROR("Search autosave database integrity check failed - %s", resultText.ascii().data());
        return false;
    }

    return true;
}

void SearchPopupMenuDB::deleteAllDatabaseFiles()
{
    closeDatabase();

    FileSystem::deleteFile(m_databaseFilename);
    FileSystem::deleteFile(m_databaseFilename + "-shm");
    FileSystem::deleteFile(m_databaseFilename + "-wal");
}

bool SearchPopupMenuDB::openDatabase()
{
    bool existsDatabaseFile = SQLiteFileSystem::ensureDatabaseFileExists(m_databaseFilename, false);

    if (existsDatabaseFile) {
        if (m_database.open(m_databaseFilename)) {
            if (!checkDatabaseValidity()) {
                // delete database and try to re-create again
                LOG_ERROR("Search autosave database validity check failed, attempting to recreate the database");
                m_database.close();
                deleteAllDatabaseFiles();
                existsDatabaseFile = false;
            }
        } else {
            LOG_ERROR("Failed to open search autosave database: %s, attempting to recreate the database", m_databaseFilename.utf8().data());
            deleteAllDatabaseFiles();
            existsDatabaseFile = false;
        }
    }

    if (!existsDatabaseFile) {
        if (!FileSystem::makeAllDirectories(FileSystem::directoryName(m_databaseFilename)))
            LOG_ERROR("Failed to create the search autosave database path %s", m_databaseFilename.utf8().data());

        m_database.open(m_databaseFilename);
    }

    if (!m_database.isOpen())
        return false;

    if (!m_database.turnOnIncrementalAutoVacuum())
        LOG_ERROR("Unable to turn on incremental auto-vacuum (%d %s)", m_database.lastError(), m_database.lastErrorMsg());

    verifySchemaVersion();

    bool databaseValidity = true;
    if (!existsDatabaseFile || !m_database.tableExists("Search"))
        databaseValidity = databaseValidity && (executeSimpleSql(createSearchTableSQL) == SQLITE_DONE);

    if (!databaseValidity) {
        // give up create database at this time (search terms will not be saved)
        m_database.close();
        deleteAllDatabaseFiles();
        return false;
    }

    m_database.setSynchronous(SQLiteDatabase::SyncNormal);
    
    m_loadSearchTermsForNameStatement = createPreparedStatement(loadSearchTermsForNameSQL);
    m_insertSearchTermStatement = createPreparedStatement(insertSearchTermSQL);
    m_removeSearchTermsForNameStatement = createPreparedStatement(removeSearchTermsForNameSQL);

    return true;
}

void SearchPopupMenuDB::closeDatabase()
{
    if (m_database.isOpen()) {
        m_loadSearchTermsForNameStatement->finalize();
        m_insertSearchTermStatement->finalize();
        m_removeSearchTermsForNameStatement->finalize();
        m_database.close();
    }
}

void SearchPopupMenuDB::verifySchemaVersion()
{
    int version = SQLiteStatement(m_database, "PRAGMA user_version").getColumnInt(0);
    if (version == schemaVersion)
        return;

    switch (version) {
        // Placeholder for schema version upgrade logic
        // Ensure cases fall through to the next version's upgrade logic
    case 0:
        m_database.clearAllTables();
        break;
    default:
        // This case can be reached when downgrading versions
        LOG_ERROR("Unknown search autosave database version: %d", version);
        m_database.clearAllTables();
        break;
    }

    // Update version
    executeSimpleSql(makeString("PRAGMA user_version=", schemaVersion));
}

void SearchPopupMenuDB::checkSQLiteReturnCode(int actual)
{
    switch (actual) {
    case SQLITE_CORRUPT:
    case SQLITE_SCHEMA:
    case SQLITE_FORMAT:
    case SQLITE_NOTADB:
        // Database has been corrupted during the run
        // so we'll recreate the db.
        deleteAllDatabaseFiles();
        openDatabase();
    }
}

int SearchPopupMenuDB::executeSimpleSql(const String& sql, bool ignoreError)
{
    SQLiteStatement statement(m_database, sql);
    int ret = statement.prepareAndStep();
    statement.finalize();

    checkSQLiteReturnCode(ret);
    if (ret != SQLITE_OK && ret != SQLITE_DONE && ret != SQLITE_ROW && !ignoreError)
        LOG_ERROR("Failed to execute %s error: %s", sql.ascii().data(), m_database.lastErrorMsg());

    return ret;
}

std::unique_ptr<SQLiteStatement> SearchPopupMenuDB::createPreparedStatement(const String& sql)
{
    auto statement = makeUnique<SQLiteStatement>(m_database, sql);
    int ret = statement->prepare();
    ASSERT_UNUSED(ret, ret == SQLITE_OK);
    return statement;
}

}
