/*
 * Copyright (C) 2008, 2009 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. ``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
 * 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 "ApplicationCacheHost.h"

#if ENABLE(OFFLINE_WEB_APPLICATIONS)

#include "ApplicationCache.h"
#include "ApplicationCacheGroup.h"
#include "ApplicationCacheResource.h"
#include "DocumentLoader.h"
#include "DOMApplicationCache.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "MainResourceLoader.h"
#include "ResourceLoader.h"
#include "ResourceRequest.h"
#include "Settings.h"

namespace WebCore {

ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
    : m_domApplicationCache(0)
    , m_documentLoader(documentLoader)
    , m_defersEvents(true)
    , m_candidateApplicationCacheGroup(0)
{
    ASSERT(m_documentLoader);
}

ApplicationCacheHost::~ApplicationCacheHost()
{
    if (m_applicationCache)
        m_applicationCache->group()->disassociateDocumentLoader(m_documentLoader);
    else if (m_candidateApplicationCacheGroup)
        m_candidateApplicationCacheGroup->disassociateDocumentLoader(m_documentLoader);
}

void ApplicationCacheHost::selectCacheWithoutManifest()
{
    ApplicationCacheGroup::selectCacheWithoutManifestURL(m_documentLoader->frame());
}

void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL)
{
    ApplicationCacheGroup::selectCache(m_documentLoader->frame(), manifestURL);
}

void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData)
{
    // Check if this request should be loaded from the application cache
    if (!substituteData.isValid() && isApplicationCacheEnabled()) {
        ASSERT(!m_mainResourceApplicationCache);

        m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, m_documentLoader);

        if (m_mainResourceApplicationCache) {
            // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource.
            ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request);
            substituteData = SubstituteData(resource->data(), 
                                            resource->response().mimeType(),
                                            resource->response().textEncodingName(), KURL());
        }
    }
}

bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceRequest& request, const ResourceResponse& r)
{
    if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) {
        ASSERT(!m_mainResourceApplicationCache);
        if (isApplicationCacheEnabled()) {
            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader());

            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
                return true;
        }
    }
    return false;
}

bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest& request, const ResourceError& error)
{
    if (!error.isCancellation()) {
        ASSERT(!m_mainResourceApplicationCache);
        if (isApplicationCacheEnabled()) {
            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader);

            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
                return true;
        }
    }
    return false;
}

void ApplicationCacheHost::mainResourceDataReceived(const char*, int, long long, bool)
{
    // This method is here to facilitate alternate implemetations of this interface by the host browser.
}

void ApplicationCacheHost::failedLoadingMainResource()
{
    ApplicationCacheGroup* group = m_candidateApplicationCacheGroup;
    if (!group && m_applicationCache) {
        ASSERT(!mainResourceApplicationCache()); // If the main resource were loaded from a cache, it wouldn't fail.
        group = m_applicationCache->group();
    }
    
    if (group)
        group->failedLoadingMainResource(m_documentLoader);
}

void ApplicationCacheHost::finishedLoadingMainResource()
{
    ApplicationCacheGroup* group = candidateApplicationCacheGroup();
    if (!group && applicationCache() && !mainResourceApplicationCache())
        group = applicationCache()->group();
    
    if (group)
        group->finishedLoadingMainResource(m_documentLoader);
}

bool ApplicationCacheHost::maybeLoadResource(ResourceLoader* loader, ResourceRequest& request, const KURL& originalURL)
{
    if (!isApplicationCacheEnabled())
        return false;
    
    if (request.url() != originalURL)
        return false;

    ApplicationCacheResource* resource;
    if (!shouldLoadResourceFromApplicationCache(request, resource))
        return false;
    
    m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
    m_documentLoader->deliverSubstituteResourcesAfterDelay();
        
    return true;
}

bool ApplicationCacheHost::maybeLoadFallbackForRedirect(ResourceLoader* resourceLoader, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url()))
        if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
            return true;
    return false;
}

bool ApplicationCacheHost::maybeLoadFallbackForResponse(ResourceLoader* resourceLoader, const ResourceResponse& response)
{
    if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5)
        if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
            return true;
    return false;
}

bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader* resourceLoader, const ResourceError& error)
{
    if (!error.isCancellation())
        if (scheduleLoadFallbackResourceFromApplicationCache(resourceLoader))
            return true;
    return false;
}

bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
    ApplicationCacheResource* resource;
    if (shouldLoadResourceFromApplicationCache(request, resource)) {
        if (resource) {
            response = resource->response();
            data.append(resource->data()->data(), resource->data()->size());
        } else {
            error = documentLoader()->frameLoader()->client()->cannotShowURLError(request);
        }
        return true;
    }
    return false;
}

void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
    // If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent,
    // or if there were network errors (but not if the user canceled the download), then instead get, from the cache, the resource of the fallback entry
    // corresponding to the matched namespace.
    if ((!error.isNull() && !error.isCancellation())
         || response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5
         || !protocolHostAndPortAreEqual(request.url(), response.url())) {
        ApplicationCacheResource* resource;
        if (getApplicationCacheFallbackResource(request, resource)) {
            response = resource->response();
            data.clear();
            data.append(resource->data()->data(), resource->data()->size());
        }
    }
}

bool ApplicationCacheHost::canCacheInPageCache() const 
{
    return !applicationCache() && !candidateApplicationCacheGroup();
}

void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplicationCache)
{
    ASSERT(!m_domApplicationCache || !domApplicationCache);
    m_domApplicationCache = domApplicationCache;
}

void ApplicationCacheHost::notifyDOMApplicationCache(EventID id)
{
    if (m_defersEvents) {
        // Events are deferred until document.onload has fired.
        m_deferredEvents.append(id);
        return;
    }
    if (m_domApplicationCache) {
        ExceptionCode ec = 0;
        m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec);
        ASSERT(!ec);    
    }
}

void ApplicationCacheHost::stopDeferringEvents()
{
    RefPtr<DocumentLoader> protect(documentLoader());
    for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
        EventID id = m_deferredEvents[i];
        if (m_domApplicationCache) {
            ExceptionCode ec = 0;
            m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec);
            ASSERT(!ec);
        }
    }
    m_deferredEvents.clear();
    m_defersEvents = false;
}

void ApplicationCacheHost::setCandidateApplicationCacheGroup(ApplicationCacheGroup* group)
{
    ASSERT(!m_applicationCache);
    m_candidateApplicationCacheGroup = group;
}
    
void ApplicationCacheHost::setApplicationCache(PassRefPtr<ApplicationCache> applicationCache)
{
    if (m_candidateApplicationCacheGroup) {
        ASSERT(!m_applicationCache);
        m_candidateApplicationCacheGroup = 0;
    }

    m_applicationCache = applicationCache;
}

bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const ResourceRequest& request, ApplicationCacheResource*& resource)
{
    ApplicationCache* cache = applicationCache();
    if (!cache || !cache->isComplete())
        return false;

    // If the resource is not to be fetched using the HTTP GET mechanism or equivalent, or if its URL has a different
    // <scheme> component than the application cache's manifest, then fetch the resource normally.
    if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringCase(request.url().protocol(), cache->manifestResource()->url().protocol()))
        return false;

    // If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry
    // in the application cache, then get the resource from the cache (instead of fetching it).
    resource = cache->resourceForURL(request.url());

    // Resources that match fallback namespaces or online whitelist entries are fetched from the network,
    // unless they are also cached.
    if (!resource && (cache->urlMatchesFallbackNamespace(request.url()) || cache->isURLInOnlineWhitelist(request.url())))
        return false;

    // Resources that are not present in the manifest will always fail to load (at least, after the
    // cache has been primed the first time), making the testing of offline applications simpler.
    return true;
}

bool ApplicationCacheHost::getApplicationCacheFallbackResource(const ResourceRequest& request, ApplicationCacheResource*& resource, ApplicationCache* cache)
{
    if (!cache) {
        cache = applicationCache();
        if (!cache)
            return false;
    }
    if (!cache->isComplete())
        return false;
    
    // If the resource is not a HTTP/HTTPS GET, then abort
    if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request))
        return false;

    KURL fallbackURL;
    if (!cache->urlMatchesFallbackNamespace(request.url(), &fallbackURL))
        return false;

    resource = cache->resourceForURL(fallbackURL);
    ASSERT(resource);

    return true;
}

bool ApplicationCacheHost::scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader* loader, ApplicationCache* cache)
{
    if (!isApplicationCacheEnabled())
        return false;

    ApplicationCacheResource* resource;
    if (!getApplicationCacheFallbackResource(loader->request(), resource, cache))
        return false;

    m_documentLoader->m_pendingSubstituteResources.set(loader, resource);
    m_documentLoader->deliverSubstituteResourcesAfterDelay();
    
    loader->handle()->cancel();

    return true;
}

ApplicationCacheHost::Status ApplicationCacheHost::status() const
{
    ApplicationCache* cache = applicationCache();    
    if (!cache)
        return UNCACHED;

    switch (cache->group()->updateStatus()) {
        case ApplicationCacheGroup::Checking:
            return CHECKING;
        case ApplicationCacheGroup::Downloading:
            return DOWNLOADING;
        case ApplicationCacheGroup::Idle: {
            if (cache->group()->isObsolete())
                return OBSOLETE;
            if (cache != cache->group()->newestCache())
                return UPDATEREADY;
            return IDLE;
        }
    }

    ASSERT_NOT_REACHED();
    return UNCACHED;
}

bool ApplicationCacheHost::update()
{
    ApplicationCache* cache = applicationCache();
    if (!cache)
        return false;
    cache->group()->update(m_documentLoader->frame(), ApplicationCacheUpdateWithoutBrowsingContext);
    return true;
}

bool ApplicationCacheHost::swapCache()
{
    ApplicationCache* cache = applicationCache();
    if (!cache)
        return false;

    // If the group of application caches to which cache belongs has the lifecycle status obsolete, unassociate document from cache.
    if (cache->group()->isObsolete()) {
        cache->group()->disassociateDocumentLoader(m_documentLoader);
        return true;
    }

    // If there is no newer cache, raise an INVALID_STATE_ERR exception.
    ApplicationCache* newestCache = cache->group()->newestCache();
    if (cache == newestCache)
        return false;
    
    ASSERT(cache->group() == newestCache->group());
    setApplicationCache(newestCache);
    
    return true;
}

bool ApplicationCacheHost::isApplicationCacheEnabled()
{
    return m_documentLoader->frame()->settings()
           && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled();
}

}  // namespace WebCore

#endif  // ENABLE(OFFLINE_WEB_APPLICATIONS)
