/*
 * Copyright (C) 2008-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:
 * 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. 
 */

#pragma once

#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>

namespace WebCore {

class ApplicationCacheGroup;
class ApplicationCacheResource;
class ResourceRequest;

using FallbackURLVector = Vector<std::pair<URL, URL>>;

class ApplicationCache : public RefCounted<ApplicationCache> {
public:
    static Ref<ApplicationCache> create() { return adoptRef(*new ApplicationCache); }

    ~ApplicationCache();

    void addResource(Ref<ApplicationCacheResource>&&);

    void setManifestResource(Ref<ApplicationCacheResource>&&);
    ApplicationCacheResource* manifestResource() const { return m_manifest; }

    void setGroup(ApplicationCacheGroup*);
    ApplicationCacheGroup* group() const { return m_group; }

    bool isComplete();

    ApplicationCacheResource* resourceForRequest(const ResourceRequest&);
    ApplicationCacheResource* resourceForURL(const String& url);

    void setAllowsAllNetworkRequests(bool value) { m_allowAllNetworkRequests = value; }
    bool allowsAllNetworkRequests() const { return m_allowAllNetworkRequests; }
    void setOnlineWhitelist(const Vector<URL>& onlineWhitelist);
    const Vector<URL>& onlineWhitelist() const { return m_onlineWhitelist; }
    bool isURLInOnlineWhitelist(const URL&); // There is an entry in online whitelist that has the same origin as the resource's URL and that is a prefix match for the resource's URL.

    void setFallbackURLs(const FallbackURLVector&);
    const FallbackURLVector& fallbackURLs() const { return m_fallbackURLs; }
    bool urlMatchesFallbackNamespace(const URL&, URL* fallbackURL = nullptr);

#ifndef NDEBUG
    void dump();
#endif

    using ResourceMap = HashMap<String, RefPtr<ApplicationCacheResource>>;
    const ResourceMap& resources() const { return m_resources; }

    void setStorageID(unsigned storageID) { m_storageID = storageID; }
    unsigned storageID() const { return m_storageID; }
    void clearStorageID();

    static bool requestIsHTTPOrHTTPSGet(const ResourceRequest&);

    int64_t estimatedSizeInStorage() const { return m_estimatedSizeInStorage; }

private:
    ApplicationCache();

    ApplicationCacheGroup* m_group { nullptr };
    ResourceMap m_resources;
    ApplicationCacheResource* m_manifest { nullptr };

    bool m_allowAllNetworkRequests { false };
    Vector<URL> m_onlineWhitelist;
    FallbackURLVector m_fallbackURLs;

    // The total size of the resources belonging to this Application Cache instance.
    // This is an estimation of the size this Application Cache occupies in the database file.
    int64_t m_estimatedSizeInStorage { 0 };

    unsigned m_storageID { 0 };
};

} // namespace WebCore
