/*
 * Copyright 2010, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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 "WebCookieJar.h"

#include "JNIUtility.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebUrlLoaderClient.h"

#include <cutils/log.h>
#include <dirent.h>

#undef ASSERT
#define ASSERT(assertion, ...) do \
    if (!(assertion)) { \
        android_printLog(ANDROID_LOG_ERROR, __FILE__, __VA_ARGS__); \
    } \
while (0)

namespace android {

static WTF::Mutex instanceMutex;
static bool isFirstInstanceCreated = false;
static bool fileSchemeCookiesEnabled = false;

static const std::string& databaseDirectory()
{
    // This method may be called on any thread, as the Java method is
    // synchronized.
    static WTF::Mutex databaseDirectoryMutex;
    MutexLocker lock(databaseDirectoryMutex);
    static std::string databaseDirectory;
    if (databaseDirectory.empty()) {
        JNIEnv* env = JSC::Bindings::getJNIEnv();
        jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
        jmethodID method = env->GetStaticMethodID(bridgeClass, "getDatabaseDirectory", "()Ljava/lang/String;");
        databaseDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
        env->DeleteLocalRef(bridgeClass);
    }
    return databaseDirectory;
}

static void removeFileOrDirectory(const char* filename)
{
    struct stat filetype;
    if (stat(filename, &filetype) != 0)
        return;
    if (S_ISDIR(filetype.st_mode)) {
        DIR* directory = opendir(filename);
        if (directory) {
            while (struct dirent* entry = readdir(directory)) {
                if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
                    continue;
                std::string entryName(filename);
                entryName.append("/");
                entryName.append(entry->d_name);
                removeFileOrDirectory(entryName.c_str());
            }
            closedir(directory);
            rmdir(filename);
        }
        return;
    }
    unlink(filename);
}

static std::string databaseDirectory(bool isPrivateBrowsing)
{
    static const char* const kDatabaseFilename = "/webviewCookiesChromium.db";
    static const char* const kDatabaseFilenamePrivateBrowsing = "/webviewCookiesChromiumPrivate.db";

    std::string databaseFilePath = databaseDirectory();
    databaseFilePath.append(isPrivateBrowsing ? kDatabaseFilenamePrivateBrowsing : kDatabaseFilename);
    return databaseFilePath;
}

static scoped_refptr<WebCookieJar>* instance(bool isPrivateBrowsing)
{
    static scoped_refptr<WebCookieJar> regularInstance;
    static scoped_refptr<WebCookieJar> privateInstance;
    return isPrivateBrowsing ? &privateInstance : &regularInstance;
}

WebCookieJar* WebCookieJar::get(bool isPrivateBrowsing)
{
    MutexLocker lock(instanceMutex);
    if (!isFirstInstanceCreated && fileSchemeCookiesEnabled)
        net::CookieMonster::EnableFileScheme();
    isFirstInstanceCreated = true;
    scoped_refptr<WebCookieJar>* instancePtr = instance(isPrivateBrowsing);
    if (!instancePtr->get())
        *instancePtr = new WebCookieJar(databaseDirectory(isPrivateBrowsing));
    return instancePtr->get();
}

void WebCookieJar::cleanup(bool isPrivateBrowsing)
{
    // This is called on the UI thread.
    MutexLocker lock(instanceMutex);
    scoped_refptr<WebCookieJar>* instancePtr = instance(isPrivateBrowsing);
    *instancePtr = 0;
    removeFileOrDirectory(databaseDirectory(isPrivateBrowsing).c_str());
}

WebCookieJar::WebCookieJar(const std::string& databaseFilePath)
    : m_cookieStoreInitialized(false)
    , m_databaseFilePath(databaseFilePath)
    , m_allowCookies(true) {}

void WebCookieJar::initCookieStore() {
    MutexLocker lock(m_cookieStoreInitializeMutex);
    if (m_cookieStoreInitialized)
        return;
    // Setup the permissions for the file
    const char* cDatabasePath = m_databaseFilePath.c_str();
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
    if (access(cDatabasePath, F_OK) == 0)
        chmod(cDatabasePath, mode);
    else {
        int fd = open(cDatabasePath, O_CREAT, mode);
        if (fd >= 0)
            close(fd);
    }

    FilePath cookiePath(cDatabasePath);
    m_cookieDb = new SQLitePersistentCookieStore(cookiePath);
    m_cookieStore = new net::CookieMonster(m_cookieDb.get(), 0);
    m_cookieStoreInitialized = true;
}

bool WebCookieJar::allowCookies()
{
    MutexLocker lock(m_allowCookiesMutex);
    return m_allowCookies;
}

void WebCookieJar::setAllowCookies(bool allow)
{
    MutexLocker lock(m_allowCookiesMutex);
    m_allowCookies = allow;
}

// From CookiePolicy in chromium
int WebCookieJar::CanGetCookies(const GURL&, const GURL&) const
{
    MutexLocker lock(m_allowCookiesMutex);
    return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
}

// From CookiePolicy in chromium
int WebCookieJar::CanSetCookie(const GURL&, const GURL&, const std::string&) const
{
    MutexLocker lock(m_allowCookiesMutex);
    return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
}

net::CookieStore* WebCookieJar::cookieStore()
{
    initCookieStore();
    return m_cookieStore.get();
}

int WebCookieJar::getNumCookiesInDatabase()
{
    return cookieStore()->GetCookieMonster()->GetAllCookies().size();
}

class FlushSemaphore : public base::RefCountedThreadSafe<FlushSemaphore>
{
public:
    FlushSemaphore()
        : m_condition(&m_lock)
        , m_count(0)
    {}

    void SendFlushRequest(net::CookieMonster* monster) {
        // FlushStore() needs to run on a Chrome thread (because it will need
        // to post the callback, and it may want to do so on its own thread.)
        // We use the IO thread for this purpose.
        //
        // TODO(husky): Our threads are hidden away in various files. Clean this
        // up and consider integrating with Chrome's browser_thread.h. Might be
        // a better idea to use the DB thread here rather than the IO thread.

        base::Thread* ioThread = WebUrlLoaderClient::ioThread();
        if (ioThread) {
            Task* callback = NewRunnableMethod(this, &FlushSemaphore::Callback);
            ioThread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
                monster, &net::CookieMonster::FlushStore, callback));
        } else {
            Callback();
        }
    }

    // Block until the given number of callbacks has been made.
    void Wait(int numCallbacks) {
        base::AutoLock al(m_lock);
        int lastCount = m_count;
        while (m_count < numCallbacks) {
            // TODO(husky): Maybe use TimedWait() here? But it's not obvious what
            // to do if the flush fails. Might be okay just to let the OS kill us.
            m_condition.Wait();
            ASSERT(lastCount != m_count, "Wait finished without incrementing m_count %d %d", m_count, lastCount);
            lastCount = m_count;
        }
        m_count -= numCallbacks;
    }

private:
    friend class base::RefCounted<FlushSemaphore>;

    void Callback() {
        base::AutoLock al(m_lock);
        m_count++;
        m_condition.Broadcast();
    }

    base::Lock m_lock;
    base::ConditionVariable m_condition;
    volatile int m_count;
};

void WebCookieJar::flush()
{
    // Flush both cookie stores (private and non-private), wait for 2 callbacks.
    static scoped_refptr<FlushSemaphore> semaphore(new FlushSemaphore());
    semaphore->SendFlushRequest(get(false)->cookieStore()->GetCookieMonster());
    semaphore->SendFlushRequest(get(true)->cookieStore()->GetCookieMonster());
    semaphore->Wait(2);
}

bool WebCookieJar::acceptFileSchemeCookies()
{
    MutexLocker lock(instanceMutex);
    return fileSchemeCookiesEnabled;
}

void WebCookieJar::setAcceptFileSchemeCookies(bool accept)
{
    // The Chromium HTTP stack only reflects changes to this flag when creating
    // a new CookieMonster instance. While we could track whether any
    // CookieMonster instances currently exist, this would be complicated and is
    // not required, so we only allow this flag to be changed before the first
    // instance is created.
    MutexLocker lock(instanceMutex);
    if (!isFirstInstanceCreated)
        fileSchemeCookiesEnabled = accept;
}

}
