/*
    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
    Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
    Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#ifndef SKY_ENGINE_CORE_FETCH_RESOURCE_H_
#define SKY_ENGINE_CORE_FETCH_RESOURCE_H_

#include "sky/engine/core/fetch/ResourceLoaderOptions.h"
#include "sky/engine/platform/Timer.h"
#include "sky/engine/platform/network/ResourceError.h"
#include "sky/engine/platform/network/ResourceLoadPriority.h"
#include "sky/engine/platform/network/ResourceRequest.h"
#include "sky/engine/platform/network/ResourceResponse.h"
#include "sky/engine/wtf/HashCountedSet.h"
#include "sky/engine/wtf/HashSet.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/text/WTFString.h"

// FIXME(crbug.com/352043): This is temporarily enabled even on RELEASE to diagnose a wild crash.
#define ENABLE_RESOURCE_IS_DELETED_CHECK

namespace blink {

struct FetchInitiatorInfo;
class MemoryCache;
class ResourceClient;
class ResourcePtrBase;
class ResourceFetcher;
class InspectorResource;
class ResourceLoader;
class SharedBuffer;

// A resource that is held in the cache. Classes who want to use this object should derive
// from ResourceClient, to get the function calls in case the requested data has arrived.
// This class also does the actual communication with the loader to obtain the resource from the network.
class Resource {
    WTF_MAKE_NONCOPYABLE(Resource); WTF_MAKE_FAST_ALLOCATED;
    friend class InspectorResource;

public:
    enum Type {
        MainResource,
        Image,
        Font,
        Raw,
        LinkPrefetch,
        LinkSubresource,
        ImportResource,
        Media // Audio or video file requested by a HTML5 media element
    };

    enum Status {
        Unknown, // let cache decide what to do with it
        Pending, // only partially loaded
        Cached, // regular case
        LoadError,
        DecodeError
    };

    Resource(const ResourceRequest&, Type);
#if ENABLE(OILPAN)
    virtual ~Resource();
#else
protected:
    // Only deleteIfPossible should delete this.
    virtual ~Resource();
public:
#endif
    virtual void dispose();
    static unsigned instanceCount() { return s_instanceCount; }

    virtual void load(ResourceFetcher*, const ResourceLoaderOptions&);

    virtual void setEncoding(const String&) { }
    virtual String encoding() const { return String(); }
    virtual void appendData(const char*, int);
    virtual void error(Resource::Status);

    void setNeedsSynchronousCacheHit(bool needsSynchronousCacheHit) { m_needsSynchronousCacheHit = needsSynchronousCacheHit; }

    void setResourceError(const ResourceError& error) { m_error = error; }
    const ResourceError& resourceError() const { return m_error; }

    void setIdentifier(unsigned long identifier) { m_identifier = identifier; }
    unsigned long identifier() const { return m_identifier; }

    virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }

    ResourceRequest& mutableResourceRequest() { return m_resourceRequest; }
    const ResourceRequest& resourceRequest() const { return m_resourceRequest; }

    const KURL& url() const { return m_resourceRequest.url();}
    Type type() const { return static_cast<Type>(m_type); }
    const ResourceLoaderOptions& options() const { return m_options; }
    void setOptions(const ResourceLoaderOptions& options) { m_options = options; }

    void didChangePriority(ResourceLoadPriority, int intraPriorityValue);

    void addClient(ResourceClient*);
    void removeClient(ResourceClient*);
    bool hasClients() const { return !m_clients.isEmpty() || !m_clientsAwaitingCallback.isEmpty(); }
    bool deleteIfPossible();

    virtual void didAddClient(ResourceClient*);
    virtual void didRemoveClient(ResourceClient*) { }
    virtual void allClientsRemoved();

    unsigned count() const { return m_clients.size(); }

    Status status() const { return static_cast<Status>(m_status); }
    void setStatus(Status status) { m_status = status; }

    size_t size() const { return encodedSize() + decodedSize() + overheadSize(); }
    size_t encodedSize() const { return m_encodedSize; }
    size_t decodedSize() const { return m_decodedSize; }
    size_t overheadSize() const;

    bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.

    bool isLoading() const { return m_loading; }
    void setLoading(bool b) { m_loading = b; }
    virtual bool stillNeedsLoad() const { return false; }

    ResourceLoader* loader() const { return m_loader.get(); }

    virtual bool isImage() const { return false; }
    bool ignoreForRequestCount() const
    {
        return type() == MainResource
            || type() == LinkPrefetch
            || type() == LinkSubresource
            || type() == Media
            || type() == Raw;
    }

    // Computes the status of an object after loading.
    // Updates the expire date on the cache entry file
    void finish(double finishTime = 0.0);

    void clearLoader();

    SharedBuffer* resourceBuffer() const { return m_data.get(); }
    void setResourceBuffer(PassRefPtr<SharedBuffer>);

    virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);

    virtual void updateRequest(const ResourceRequest&) { }
    virtual void responseReceived(const ResourceResponse&);
    void setResponse(const ResourceResponse& response) { m_response = response; }
    const ResourceResponse& response() const { return m_response; }

    bool hasOneHandle() const;
    bool canDelete() const;

    // List of acceptable MIME types separated by ",".
    // A MIME type may contain a wildcard, e.g. "text/*".
    AtomicString accept() const { return m_accept; }
    void setAccept(const AtomicString& accept) { m_accept = accept; }

    bool wasCanceled() const { return m_error.isCancellation(); }
    bool errorOccurred() const { return m_status == LoadError || m_status == DecodeError; }
    bool loadFailedOrCanceled() { return !m_error.isNull(); }

    DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy; }
    void setDataBufferingPolicy(DataBufferingPolicy);

    void registerHandle(ResourcePtrBase* h);
    void unregisterHandle(ResourcePtrBase* h);

    bool mustRevalidateDueToCacheHeaders();
    bool canUseCacheValidator();
    bool isCacheValidator() const { return m_resourceToRevalidate; }
    Resource* resourceToRevalidate() const { return m_resourceToRevalidate; }
    void setResourceToRevalidate(Resource*);
    bool hasCacheControlNoStoreHeader();

    bool isPurgeable() const;
    bool wasPurged() const;
    bool lock();

    virtual void didSendData(unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { }
    virtual void didDownloadData(int) { }

    double loadFinishTime() const { return m_loadFinishTime; }

    virtual bool canReuse(const ResourceRequest&) const { return true; }

    // Used by the MemoryCache to reduce the memory consumption of the entry.
    void prune();

    static const char* resourceTypeToString(Type, const FetchInitiatorInfo&);

#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
    void assertAlive() const { RELEASE_ASSERT(!m_deleted); }
#else
    void assertAlive() const { }
#endif

protected:
    virtual void checkNotify();
    virtual void finishOnePart();

    // Normal resource pointers will silently switch what Resource* they reference when we
    // successfully revalidated the resource. We need a way to guarantee that the Resource
    // that received the 304 response survives long enough to switch everything over to the
    // revalidatedresource. The normal mechanisms for keeping a Resource alive externally
    // (ResourcePtrs and ResourceClients registering themselves) don't work in this case, so
    // have a separate internal protector).
    class InternalResourcePtr {
    public:
        explicit InternalResourcePtr(Resource* resource)
            : m_resource(resource)
        {
            m_resource->incrementProtectorCount();
        }

        ~InternalResourcePtr()
        {
            m_resource->decrementProtectorCount();
            m_resource->deleteIfPossible();
        }
    private:
        Resource* m_resource;
    };

    void incrementProtectorCount() { m_protectorCount++; }
    void decrementProtectorCount() { m_protectorCount--; }

    void setEncodedSize(size_t);
    void setDecodedSize(size_t);
    void didAccessDecodedData();

    virtual void switchClientsToRevalidatedResource();
    void clearResourceToRevalidate();
    void updateResponseAfterRevalidation(const ResourceResponse& validatingResponse);

    void finishPendingClients();

    HashCountedSet<ResourceClient*> m_clients;
    HashCountedSet<ResourceClient*> m_clientsAwaitingCallback;

    class ResourceCallback {
    public:
        static ResourceCallback* callbackHandler();
        void schedule(Resource*);
        void cancel(Resource*);
        bool isScheduled(Resource*) const;
    private:
        ResourceCallback();
        void timerFired(Timer<ResourceCallback>*);
        Timer<ResourceCallback> m_callbackTimer;
        HashSet<Resource*> m_resourcesWithPendingClients;
    };

    bool hasClient(ResourceClient* client) { return m_clients.contains(client) || m_clientsAwaitingCallback.contains(client); }

    virtual bool isSafeToUnlock() const { return false; }
    virtual void destroyDecodedDataIfPossible() { }

    ResourceRequest m_resourceRequest;
    AtomicString m_accept;
    RefPtr<ResourceLoader> m_loader;
    ResourceLoaderOptions m_options;

    ResourceResponse m_response;
    double m_responseTimestamp;

    RefPtr<SharedBuffer> m_data;
    Timer<Resource> m_cancelTimer;

private:
    bool addClientToSet(ResourceClient*);
    void cancelTimerFired(Timer<Resource>*);

    void revalidationSucceeded(const ResourceResponse&);
    void revalidationFailed();

    bool unlock();

    bool hasRightHandleCountApartFromCache(unsigned targetCount) const;

    void failBeforeStarting();

    String m_fragmentIdentifierForRequest;

    ResourceError m_error;

    double m_loadFinishTime;

    unsigned long m_identifier;

    size_t m_encodedSize;
    size_t m_decodedSize;
    unsigned m_handleCount;
    unsigned m_protectorCount;

    unsigned m_requestedFromNetworkingLayer : 1;

    unsigned m_loading : 1;

    unsigned m_switchingClientsToRevalidatedResource : 1;

    unsigned m_type : 4; // Type
    unsigned m_status : 3; // Status

    unsigned m_wasPurged : 1;

    unsigned m_needsSynchronousCacheHit : 1;

#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
    bool m_deleted;
#endif

    // If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
    // using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
    // to to be clients of m_resourceToRevalidate and the resource is deleted. If not, the field is zeroed and this
    // resources becomes normal resource load.
    RawPtr<Resource> m_resourceToRevalidate;

    // If this field is non-null, the resource has a proxy for checking whether it is still up to date (see m_resourceToRevalidate).
    RawPtr<Resource> m_proxyResource;

    // These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
    HashSet<ResourcePtrBase*> m_handlesToRevalidate;

    static unsigned s_instanceCount;
};

#if !LOG_DISABLED
// Intended to be used in LOG statements.
const char* ResourceTypeName(Resource::Type);
#endif

#define DEFINE_RESOURCE_TYPE_CASTS(typeName) \
    DEFINE_TYPE_CASTS(typeName##Resource, Resource, resource, resource->type() == Resource::typeName, resource.type() == Resource::typeName); \
    inline typeName##Resource* to##typeName##Resource(const ResourcePtr<Resource>& ptr) { return to##typeName##Resource(ptr.get()); }

}

#endif  // SKY_ENGINE_CORE_FETCH_RESOURCE_H_
