/*
 * 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 "WebCache.h"

#include "JNIUtility.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebUrlLoaderClient.h"
#include "net/http/http_network_session.h"
#include <wtf/text/CString.h>

using namespace WTF;
using namespace disk_cache;
using namespace net;
using namespace std;

namespace android {

static WTF::Mutex instanceMutex;

static string storageDirectory()
{
    static const char* const kDirectory = "/webviewCacheChromium";

    JNIEnv* env = JSC::Bindings::getJNIEnv();
    jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
    jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;");
    string storageDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
    env->DeleteLocalRef(bridgeClass);

    // Return empty string if storageDirectory is an empty string
    if (storageDirectory.empty())
        return storageDirectory;

    storageDirectory.append(kDirectory);
    return storageDirectory;
}

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

WebCache* WebCache::get(bool isPrivateBrowsing)
{
    MutexLocker lock(instanceMutex);
    scoped_refptr<WebCache>* instancePtr = instance(isPrivateBrowsing);
    if (!instancePtr->get())
        *instancePtr = new WebCache(isPrivateBrowsing);
    return instancePtr->get();
}

void WebCache::cleanup(bool isPrivateBrowsing)
{
    MutexLocker lock(instanceMutex);
    scoped_refptr<WebCache>* instancePtr = instance(isPrivateBrowsing);
    *instancePtr = 0;
}

WebCache::WebCache(bool isPrivateBrowsing)
    : m_doomAllEntriesCallback(this, &WebCache::doomAllEntries)
    , m_onClearDoneCallback(this, &WebCache::onClearDone)
    , m_isClearInProgress(false)
    , m_openEntryCallback(this, &WebCache::openEntry)
    , m_onGetEntryDoneCallback(this, &WebCache::onGetEntryDone)
    , m_isGetEntryInProgress(false)
    , m_cacheBackend(0)
{
    base::Thread* ioThread = WebUrlLoaderClient::ioThread();
    scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();

    static const int kMaximumCacheSizeBytes = 20 * 1024 * 1024;
    m_hostResolver = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0);

    m_proxyConfigService = new ProxyConfigServiceAndroid();
    net::HttpCache::BackendFactory* backendFactory;
    if (isPrivateBrowsing)
        backendFactory = net::HttpCache::DefaultBackend::InMemory(kMaximumCacheSizeBytes / 2);
    else {
        string storage(storageDirectory());
        if (storage.empty()) // Can't get a storage directory from the OS
            backendFactory = net::HttpCache::DefaultBackend::InMemory(kMaximumCacheSizeBytes / 2);
        else {
            FilePath directoryPath(storage.c_str());
            backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy);
        }
    }

    m_cache = new net::HttpCache(m_hostResolver.get(),
                                 new CertVerifier(),
                                 0, // dnsrr_resolver
                                 0, // dns_cert_checker
                                 net::ProxyService::CreateWithoutProxyResolver(m_proxyConfigService, 0 /* net_log */),
                                 net::SSLConfigService::CreateSystemSSLConfigService(),
                                 net::HttpAuthHandlerFactory::CreateDefault(m_hostResolver.get()),
                                 0, // network_delegate
                                 0, // net_log
                                 backendFactory);
}

void WebCache::clear()
{
    base::Thread* thread = WebUrlLoaderClient::ioThread();
    if (thread)
        thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::clearImpl));
}

void WebCache::certTrustChanged()
{
    base::Thread* thread = WebUrlLoaderClient::ioThread();
    if (thread)
        thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::certTrustChangedImpl));
}

void WebCache::certTrustChangedImpl()
{
    net::HttpNetworkSession* session = m_cache->GetSession();
    if (session)
        session->cert_verifier()->ClearCache();
    m_cache->CloseAllConnections();
}

void WebCache::closeIdleConnections()
{
    base::Thread* thread = WebUrlLoaderClient::ioThread();
    if (thread)
        thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::closeIdleImpl));
}

void WebCache::closeIdleImpl()
{
    m_cache->CloseIdleConnections();
}

void WebCache::clearImpl()
{
    if (m_isClearInProgress)
        return;
    m_isClearInProgress = true;

    if (!m_cacheBackend) {
        int code = m_cache->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback);
        // Code ERR_IO_PENDING indicates that the operation is still in progress and
        // the supplied callback will be invoked when it completes.
        if (code == ERR_IO_PENDING)
            return;
        else if (code != OK) {
            onClearDone(0 /*unused*/);
            return;
        }
    }
    doomAllEntries(0 /*unused*/);
}

void WebCache::doomAllEntries(int)
{
    if (!m_cacheBackend) {
        onClearDone(0 /*unused*/);
        return;
    }

    // Code ERR_IO_PENDING indicates that the operation is still in progress and
    // the supplied callback will be invoked when it completes.
    if (m_cacheBackend->DoomAllEntries(&m_onClearDoneCallback) == ERR_IO_PENDING)
        return;
    onClearDone(0 /*unused*/);
}

void WebCache::onClearDone(int)
{
    m_isClearInProgress = false;
}

scoped_refptr<CacheResult> WebCache::getCacheResult(String url)
{
    // This is called on the UI thread.
    MutexLocker lock(m_getEntryMutex);
    if (m_isGetEntryInProgress)
        return 0; // TODO: OK? Or can we queue 'em up?

    // The Chromium methods are asynchronous, but we need this method to be
    // synchronous. Do the work on the Chromium thread but block this thread
    // here waiting for the work to complete.
    base::Thread* thread = WebUrlLoaderClient::ioThread();
    if (!thread)
        return 0;

    m_entry = 0;
    m_isGetEntryInProgress = true;
    m_entryUrl = url.threadsafeCopy();
    thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::getEntryImpl));

    while (m_isGetEntryInProgress)
        m_getEntryCondition.wait(m_getEntryMutex);

    if (!m_entry)
        return 0;

    return new CacheResult(m_entry, url);
}

void WebCache::getEntryImpl()
{
    if (!m_cacheBackend) {
        int code = m_cache->GetBackend(&m_cacheBackend, &m_openEntryCallback);
        if (code == ERR_IO_PENDING)
            return;
        else if (code != OK) {
            onGetEntryDone(0 /*unused*/);
            return;
        }
    }
    openEntry(0 /*unused*/);
}

void WebCache::openEntry(int)
{
    if (!m_cacheBackend) {
        onGetEntryDone(0 /*unused*/);
        return;
    }

    if (m_cacheBackend->OpenEntry(string(m_entryUrl.utf8().data()), &m_entry, &m_onGetEntryDoneCallback) == ERR_IO_PENDING)
        return;
    onGetEntryDone(0 /*unused*/);
}

void WebCache::onGetEntryDone(int)
{
    // Unblock the UI thread in getEntry();
    MutexLocker lock(m_getEntryMutex);
    m_isGetEntryInProgress = false;
    m_getEntryCondition.signal();
}

} // namespace android
