/*
 * Copyright (c) 2009, Google Inc. All rights reserved.
 * Copyright (c) 2017 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:
 * 
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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.
 */

#pragma once

#include <wtf/Deque.h>
#include <wtf/URL.h>
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>

namespace WebCore {

class ApplicationCache;
class ApplicationCacheGroup;
class ApplicationCacheResource;
class ApplicationCacheStorage;
class DOMApplicationCache;
class DocumentLoader;
class Frame;
class ResourceError;
class ResourceLoader;
class ResourceRequest;
class ResourceResponse;
class SharedBuffer;
class SubstituteData;

class ApplicationCacheHost {
    WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); WTF_MAKE_FAST_ALLOCATED;
public:
    // The Status numeric values are specified in the HTML5 spec.
    enum Status {
        UNCACHED = 0,
        IDLE = 1,
        CHECKING = 2,
        DOWNLOADING = 3,
        UPDATEREADY = 4,
        OBSOLETE = 5
    };

    struct CacheInfo {
        URL manifest;
        double creationTime;
        double updateTime;
        long long size;
    };

    struct ResourceInfo {
        URL resource;
        bool isMaster;
        bool isManifest;
        bool isFallback;
        bool isForeign;
        bool isExplicit;
        long long size;
    };

    explicit ApplicationCacheHost(DocumentLoader&);
    ~ApplicationCacheHost();

    static URL createFileURL(const String&);

    void selectCacheWithoutManifest();
    void selectCacheWithManifest(const URL& manifestURL);

    void maybeLoadMainResource(const ResourceRequest&, SubstituteData&);
    void maybeLoadMainResourceForRedirect(const ResourceRequest&, SubstituteData&);
    bool maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse&);
    void mainResourceDataReceived(const char* data, int length, long long encodedDataLength, bool allAtOnce);
    void finishedLoadingMainResource();
    void failedLoadingMainResource();

    WEBCORE_EXPORT bool maybeLoadResource(ResourceLoader&, const ResourceRequest&, const URL& originalURL);
    WEBCORE_EXPORT bool maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&);
    WEBCORE_EXPORT bool maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&);
    WEBCORE_EXPORT bool maybeLoadFallbackForError(ResourceLoader*, const ResourceError&);

    bool maybeLoadSynchronously(ResourceRequest&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>&);
    void maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>&);

    bool canCacheInBackForwardCache();

    Status status() const;
    bool update();
    bool swapCache();
    void abort();

    void setDOMApplicationCache(DOMApplicationCache*);
    void notifyDOMApplicationCache(const AtomString& eventType, int progressTotal, int progressDone);

    void stopLoadingInFrame(Frame&);

    void stopDeferringEvents(); // Also raises the events that have been queued up.

    Vector<ResourceInfo> resourceList();
    CacheInfo applicationCacheInfo();

    bool shouldLoadResourceFromApplicationCache(const ResourceRequest&, ApplicationCacheResource*&);
    bool getApplicationCacheFallbackResource(const ResourceRequest&, ApplicationCacheResource*&, ApplicationCache* = nullptr);

private:
    friend class ApplicationCacheGroup;

    struct DeferredEvent {
        AtomString eventType;
        int progressTotal;
        int progressDone;
    };

    bool isApplicationCacheEnabled();
    bool isApplicationCacheBlockedForRequest(const ResourceRequest&);

    void dispatchDOMEvent(const AtomString& eventType, int progressTotal, int progressDone);

    bool scheduleLoadFallbackResourceFromApplicationCache(ResourceLoader*, ApplicationCache* = nullptr);
    void setCandidateApplicationCacheGroup(ApplicationCacheGroup*);
    ApplicationCacheGroup* candidateApplicationCacheGroup() const;
    void setApplicationCache(RefPtr<ApplicationCache>&&);
    ApplicationCache* applicationCache() const { return m_applicationCache.get(); }
    ApplicationCache* mainResourceApplicationCache() const { return m_mainResourceApplicationCache.get(); }
    bool maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError&);

    WeakPtr<DOMApplicationCache> m_domApplicationCache;
    DocumentLoader& m_documentLoader;

    bool m_defersEvents { true }; // Events are deferred until after document onload.
    Vector<DeferredEvent> m_deferredEvents;

    // The application cache that the document loader is associated with (if any).
    RefPtr<ApplicationCache> m_applicationCache;

    // Before an application cache has finished loading, this will be the candidate application
    // group that the document loader is associated with.
    WeakPtr<ApplicationCacheGroup> m_candidateApplicationCacheGroup;

    // This is the application cache the main resource was loaded from (if any).
    RefPtr<ApplicationCache> m_mainResourceApplicationCache;
};

}  // namespace WebCore
