/*
    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 Resource_h
#define Resource_h

#include <memory>
#include "platform/MemoryCoordinator.h"
#include "platform/PlatformExport.h"
#include "platform/SharedBuffer.h"
#include "platform/Timer.h"
#include "platform/WebTaskRunner.h"
#include "platform/instrumentation/tracing/web_process_memory_dump.h"
#include "platform/loader/fetch/CachedMetadataHandler.h"
#include "platform/loader/fetch/IntegrityMetadata.h"
#include "platform/loader/fetch/ResourceError.h"
#include "platform/loader/fetch/ResourceLoadPriority.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/loader/fetch/ResourceRequest.h"
#include "platform/loader/fetch/ResourceResponse.h"
#include "platform/loader/fetch/ResourceStatus.h"
#include "platform/wtf/Allocator.h"
#include "platform/wtf/AutoReset.h"
#include "platform/wtf/HashCountedSet.h"
#include "platform/wtf/HashSet.h"
#include "platform/wtf/text/AtomicString.h"
#include "platform/wtf/text/WTFString.h"
#include "public/platform/WebDataConsumerHandle.h"

namespace blink {

class FetchParameters;
class ResourceClient;
class ResourceFetcher;
class ResourceTimingInfo;
class ResourceLoader;
class SecurityOrigin;

// 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 PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
                                 public MemoryCoordinatorClient {
  USING_GARBAGE_COLLECTED_MIXIN(Resource);
  WTF_MAKE_NONCOPYABLE(Resource);

 public:
  // |Type| enum values are used in UMAs, so do not change the values of
  // existing |Type|. When adding a new |Type|, append it at the end and update
  // |kLastResourceType|.
  enum Type {
    kMainResource,
    kImage,
    kCSSStyleSheet,
    kScript,
    kFont,
    kRaw,
    kSVGDocument,
    kXSLStyleSheet,
    kLinkPrefetch,
    kTextTrack,
    kImportResource,
    kMedia,  // Audio or video file requested by a HTML5 media element
    kManifest,
    kMock  // Only for testing
  };
  static const int kLastResourceType = kMock + 1;

  // Whether a resource client for a preload should mark the preload as
  // referenced.
  enum PreloadReferencePolicy {
    kMarkAsReferenced,
    kDontMarkAsReferenced,
  };

  // Used by reloadIfLoFiOrPlaceholderImage().
  enum ReloadLoFiOrPlaceholderPolicy {
    kReloadIfNeeded,
    kReloadAlways,
  };

  virtual ~Resource();

  DECLARE_VIRTUAL_TRACE();

  virtual void SetEncoding(const String&) {}
  virtual String Encoding() const { return String(); }
  virtual void AppendData(const char*, size_t);
  virtual void FinishAsError(const ResourceError&);
  virtual void SetCORSFailed() {}

  void SetNeedsSynchronousCacheHit(bool needs_synchronous_cache_hit) {
    needs_synchronous_cache_hit_ = needs_synchronous_cache_hit;
  }

  void SetLinkPreload(bool is_link_preload) { link_preload_ = is_link_preload; }
  bool IsLinkPreload() const { return link_preload_; }

  void SetPreloadDiscoveryTime(double preload_discovery_time) {
    preload_discovery_time_ = preload_discovery_time;
  }

  const ResourceError& GetResourceError() const { return error_; }

  void SetIdentifier(unsigned long identifier) { identifier_ = identifier; }
  unsigned long Identifier() const { return identifier_; }

  virtual bool ShouldIgnoreHTTPStatusCodeErrors() const { return false; }

  const ResourceRequest& GetResourceRequest() const {
    return resource_request_;
  }
  const ResourceRequest& LastResourceRequest() const;

  virtual void SetRevalidatingRequest(const ResourceRequest&);

  void SetFetcherSecurityOrigin(SecurityOrigin* origin) {
    fetcher_security_origin_ = origin;
  }

  // This url can have a fragment, but it can match resources that differ by the
  // fragment only.
  const KURL& Url() const { return GetResourceRequest().Url(); }
  Type GetType() const { return static_cast<Type>(type_); }
  const ResourceLoaderOptions& Options() const { return options_; }
  ResourceLoaderOptions& MutableOptions() { return options_; }

  void DidChangePriority(ResourceLoadPriority, int intra_priority_value);
  virtual ResourcePriority PriorityFromObservers() {
    return ResourcePriority();
  }

  // The reference policy indicates that the client should not affect whether
  // a preload is considered referenced or not. This allows for "passive"
  // resource clients that simply observe the resource.
  void AddClient(ResourceClient*, PreloadReferencePolicy = kMarkAsReferenced);
  void RemoveClient(ResourceClient*);

  enum PreloadResult {
    kPreloadNotReferenced,
    kPreloadReferenced,
    kPreloadReferencedWhileLoading,
    kPreloadReferencedWhileComplete
  };
  PreloadResult GetPreloadResult() const { return preload_result_; }

  ResourceStatus GetStatus() const { return status_; }
  void SetStatus(ResourceStatus status) { status_ = status; }

  size_t size() const { return EncodedSize() + DecodedSize() + OverheadSize(); }

  // Returns the size of content (response body) before decoding. Adding a new
  // usage of this function is not recommended (See the TODO below).
  //
  // TODO(hiroshige): Now encodedSize/decodedSize states are inconsistent and
  // need to be refactored (crbug/643135).
  size_t EncodedSize() const { return encoded_size_; }

  // Returns the current memory usage for the encoded data. Adding a new usage
  // of this function is not recommended as the same reason as |encodedSize()|.
  //
  // |encodedSize()| and |encodedSizeMemoryUsageForTesting()| can return
  // different values, e.g., when ImageResource purges encoded image data after
  // finishing loading.
  size_t EncodedSizeMemoryUsageForTesting() const {
    return encoded_size_memory_usage_;
  }

  size_t DecodedSize() const { return decoded_size_; }
  size_t OverheadSize() const { return overhead_size_; }

  bool IsLoaded() const { return status_ > ResourceStatus::kPending; }

  bool IsLoading() const { return status_ == ResourceStatus::kPending; }
  bool StillNeedsLoad() const { return status_ < ResourceStatus::kPending; }

  void SetLoader(ResourceLoader*);
  ResourceLoader* Loader() const { return loader_.Get(); }

  virtual bool IsImage() const { return false; }
  bool ShouldBlockLoadEvent() const;
  bool IsLoadEventBlockingResourceType() const;

  // Computes the status of an object after loading. Updates the expire date on
  // the cache entry file
  virtual void Finish(double finish_time);
  void Finish() { Finish(0.0); }

  bool PassesAccessControlCheck(const SecurityOrigin*) const;

  virtual PassRefPtr<const SharedBuffer> ResourceBuffer() const {
    return data_;
  }
  void SetResourceBuffer(PassRefPtr<SharedBuffer>);

  virtual bool WillFollowRedirect(const ResourceRequest&,
                                  const ResourceResponse&);

  // Called when a redirect response was received but a decision has already
  // been made to not follow it.
  virtual void WillNotFollowRedirect() {}

  virtual void ResponseReceived(const ResourceResponse&,
                                std::unique_ptr<WebDataConsumerHandle>);
  void SetResponse(const ResourceResponse&);
  const ResourceResponse& GetResponse() const { return response_; }

  virtual void ReportResourceTimingToClients(const ResourceTimingInfo&) {}

  // Sets the serialized metadata retrieved from the platform's cache.
  virtual void SetSerializedCachedMetadata(const char*, size_t);

  // This may return nullptr when the resource isn't cacheable.
  CachedMetadataHandler* CacheHandler();

  AtomicString HttpContentType() const;

  bool WasCanceled() const { return error_.IsCancellation(); }
  bool ErrorOccurred() const {
    return status_ == ResourceStatus::kLoadError ||
           status_ == ResourceStatus::kDecodeError;
  }
  bool LoadFailedOrCanceled() const { return !error_.IsNull(); }

  DataBufferingPolicy GetDataBufferingPolicy() const {
    return options_.data_buffering_policy;
  }
  void SetDataBufferingPolicy(DataBufferingPolicy);

  // The isPreloaded() flag is using a counter in order to make sure that even
  // when multiple ResourceFetchers are preloading the resource, it will remain
  // marked as preloaded until *all* of them have used it.
  bool IsUnusedPreload() const {
    return IsPreloaded() && GetPreloadResult() == kPreloadNotReferenced;
  }
  bool IsPreloaded() const { return preload_count_; }
  void IncreasePreloadCount() { ++preload_count_; }
  void DecreasePreloadCount() {
    DCHECK(preload_count_);
    --preload_count_;
  }

  bool CanReuseRedirectChain() const;
  bool MustRevalidateDueToCacheHeaders() const;
  bool CanUseCacheValidator() const;
  bool IsCacheValidator() const { return is_revalidating_; }
  bool HasCacheControlNoStoreHeader() const;
  bool MustReloadDueToVaryHeader(const ResourceRequest& new_request) const;

  bool IsEligibleForIntegrityCheck(SecurityOrigin*) const;

  void SetIntegrityMetadata(const IntegrityMetadataSet& metadata) {
    integrity_metadata_ = metadata;
  }
  const IntegrityMetadataSet& IntegrityMetadata() const {
    return integrity_metadata_;
  }
  // The argument must never be |NotChecked|.
  void SetIntegrityDisposition(ResourceIntegrityDisposition);
  ResourceIntegrityDisposition IntegrityDisposition() const {
    return integrity_disposition_;
  }
  bool MustRefetchDueToIntegrityMetadata(const FetchParameters&) const;

  bool IsAlive() const { return is_alive_; }

  void SetCacheIdentifier(const String& cache_identifier) {
    cache_identifier_ = cache_identifier;
  }
  String CacheIdentifier() const { return cache_identifier_; }

  virtual void DidSendData(unsigned long long /* bytesSent */,
                           unsigned long long /* totalBytesToBeSent */) {}
  virtual void DidDownloadData(int) {}

  double LoadFinishTime() const { return load_finish_time_; }

  void SetEncodedDataLength(int64_t value) {
    response_.SetEncodedDataLength(value);
  }
  void SetEncodedBodyLength(int value) {
    response_.SetEncodedBodyLength(value);
  }
  void SetDecodedBodyLength(int value) {
    response_.SetDecodedBodyLength(value);
  }

  virtual bool CanReuse(const FetchParameters&) const { return true; }

  // If cache-aware loading is activated, this callback is called when the first
  // disk-cache-only request failed due to cache miss. After this callback,
  // cache-aware loading is deactivated and a reload with original request will
  // be triggered right away in ResourceLoader.
  virtual void WillReloadAfterDiskCacheMiss() {}

  // TODO(shaochuan): This is for saving back the actual ResourceRequest sent
  // in ResourceFetcher::startLoad() for retry in cache-aware loading, remove
  // once ResourceRequest is not modified in startLoad(). crbug.com/632580
  void SetResourceRequest(const ResourceRequest& resource_request) {
    resource_request_ = resource_request;
  }

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

  virtual void OnMemoryDump(WebMemoryDumpLevelOfDetail,
                            WebProcessMemoryDump*) const;

  // If this Resource is ImageResource and has the Lo-Fi response headers or is
  // a placeholder, reload the full original image with the Lo-Fi state set to
  // off and optionally bypassing the cache.
  virtual void ReloadIfLoFiOrPlaceholderImage(ResourceFetcher*,
                                              ReloadLoFiOrPlaceholderPolicy) {}

  // Used to notify ImageResourceContent of the start of actual loading.
  // JavaScript calls or client/observer notifications are disallowed inside
  // notifyStartLoad().
  virtual void NotifyStartLoad() {}

  static const char* ResourceTypeToString(
      Type,
      const AtomicString& fetch_initiator_name);

  class ProhibitAddRemoveClientInScope : public AutoReset<bool> {
   public:
    ProhibitAddRemoveClientInScope(Resource* resource)
        : AutoReset(&resource->is_add_remove_client_prohibited_, true) {}
  };

  class RevalidationStartForbiddenScope : public AutoReset<bool> {
   public:
    RevalidationStartForbiddenScope(Resource* resource)
        : AutoReset(&resource->is_revalidation_start_forbidden_, true) {}
  };

 protected:
  Resource(const ResourceRequest&, Type, const ResourceLoaderOptions&);

  virtual void CheckNotify();

  void MarkClientFinished(ResourceClient*);

  virtual bool HasClientsOrObservers() const {
    return !clients_.IsEmpty() || !clients_awaiting_callback_.IsEmpty() ||
           !finished_clients_.IsEmpty();
  }
  virtual void DestroyDecodedDataForFailedRevalidation() {}

  void SetEncodedSize(size_t);
  void SetDecodedSize(size_t);

  void FinishPendingClients();

  virtual void DidAddClient(ResourceClient*);
  void WillAddClientOrObserver(PreloadReferencePolicy);

  void DidRemoveClientOrObserver();
  virtual void AllClientsAndObserversRemoved();

  bool HasClient(ResourceClient* client) const {
    return clients_.Contains(client) ||
           clients_awaiting_callback_.Contains(client) ||
           finished_clients_.Contains(client);
  }

  struct RedirectPair {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

   public:
    explicit RedirectPair(const ResourceRequest& request,
                          const ResourceResponse& redirect_response)
        : request_(request), redirect_response_(redirect_response) {}

    ResourceRequest request_;
    ResourceResponse redirect_response_;
  };
  const Vector<RedirectPair>& RedirectChain() const { return redirect_chain_; }

  virtual void DestroyDecodedDataIfPossible() {}

  // Returns the memory dump name used for tracing. See Resource::onMemoryDump.
  String GetMemoryDumpName() const;

  const HeapHashCountedSet<WeakMember<ResourceClient>>& Clients() const {
    return clients_;
  }

  void SetCachePolicyBypassingCache();
  void SetPreviewsState(WebURLRequest::PreviewsState);
  void ClearRangeRequestHeader();

  SharedBuffer* Data() const { return data_.Get(); }
  void ClearData();

 private:
  class CachedMetadataHandlerImpl;
  class ServiceWorkerResponseCachedMetadataHandler;

  void CancelTimerFired(TimerBase*);

  void RevalidationSucceeded(const ResourceResponse&);
  void RevalidationFailed();

  size_t CalculateOverheadSize() const;

  String ReasonNotDeletable() const;

  // MemoryCoordinatorClient overrides:
  void OnPurgeMemory() override;

  Member<CachedMetadataHandlerImpl> cache_handler_;
  RefPtr<SecurityOrigin> fetcher_security_origin_;

  ResourceError error_;

  double load_finish_time_;

  unsigned long identifier_;

  size_t encoded_size_;
  size_t encoded_size_memory_usage_;
  size_t decoded_size_;

  // Resource::calculateOverheadSize() is affected by changes in
  // |m_resourceRequest.url()|, but |m_overheadSize| is not updated after
  // initial |m_resourceRequest| is given, to reduce MemoryCache manipulation
  // and thus potential bugs. crbug.com/594644
  const size_t overhead_size_;

  unsigned preload_count_;

  double preload_discovery_time_;

  String cache_identifier_;

  PreloadResult preload_result_;
  Type type_;
  ResourceStatus status_;

  bool needs_synchronous_cache_hit_;
  bool link_preload_;
  bool is_revalidating_;
  bool is_alive_;
  bool is_add_remove_client_prohibited_;
  bool is_revalidation_start_forbidden_ = false;

  ResourceIntegrityDisposition integrity_disposition_;
  IntegrityMetadataSet integrity_metadata_;

  // Ordered list of all redirects followed while fetching this resource.
  Vector<RedirectPair> redirect_chain_;

  HeapHashCountedSet<WeakMember<ResourceClient>> clients_;
  HeapHashCountedSet<WeakMember<ResourceClient>> clients_awaiting_callback_;
  HeapHashCountedSet<WeakMember<ResourceClient>> finished_clients_;

  ResourceLoaderOptions options_;

  double response_timestamp_;

  TaskRunnerTimer<Resource> cancel_timer_;
  TaskHandle async_finish_pending_clients_task_;

  ResourceRequest resource_request_;
  Member<ResourceLoader> loader_;
  ResourceResponse response_;

  RefPtr<SharedBuffer> data_;
};

class ResourceFactory {
  STACK_ALLOCATED();

 public:
  virtual Resource* Create(const ResourceRequest&,
                           const ResourceLoaderOptions&,
                           const String&) const = 0;
  Resource::Type GetType() const { return type_; }

 protected:
  explicit ResourceFactory(Resource::Type type) : type_(type) {}

  Resource::Type type_;
};

#define DEFINE_RESOURCE_TYPE_CASTS(typeName)                      \
  DEFINE_TYPE_CASTS(typeName##Resource, Resource, resource,       \
                    resource->GetType() == Resource::k##typeName, \
                    resource.GetType() == Resource::k##typeName);

}  // namespace blink

#endif
