// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_IMAGE_RESOURCE_CONTENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_IMAGE_RESOURCE_CONTENT_H_

#include <memory>
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_status.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"

namespace blink {

class ExecutionContext;
class FetchParameters;
class ImageResourceInfo;
class ImageResourceObserver;
class ResourceError;
class ResourceFetcher;
class ResourceResponse;
class UseCounter;

// ImageResourceContent is a container that holds fetch result of
// an ImageResource in a decoded form.
// Classes that use the fetched images
// should hold onto this class and/or inherit ImageResourceObserver,
// instead of holding onto ImageResource or inheriting ResourceClient.
// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit?usp=sharing
// TODO(hiroshige): Make ImageResourceContent ResourceClient and remove the
// word 'observer' from ImageResource.
class CORE_EXPORT ImageResourceContent final
    : public GarbageCollected<ImageResourceContent>,
      public ImageObserver {
 public:
  // Used for loading.
  // Returned content will be associated immediately later with ImageResource.
  static ImageResourceContent* CreateNotStarted() {
    return MakeGarbageCollected<ImageResourceContent>(nullptr);
  }

  // Creates ImageResourceContent from an already loaded image.
  static ImageResourceContent* CreateLoaded(scoped_refptr<blink::Image>);

  static ImageResourceContent* Fetch(FetchParameters&, ResourceFetcher*);

  explicit ImageResourceContent(scoped_refptr<blink::Image> = nullptr);

  // Returns the NullImage() if the image is not available yet.
  blink::Image* GetImage() const;
  bool HasImage() const { return image_.get(); }

  // Returns true if enough of the image has been decoded to allow its size to
  // be determined. If this returns true, so will HasImage().
  bool IsSizeAvailable() const {
    return size_available_ != Image::kSizeUnavailable;
  }

  // Returns the intrinsic width and height of the image, or 0x0 if no image
  // exists. IsSizeAvailable() can be used to determine if the value returned is
  // reliable. If the image is a BitmapImage, then this corresponds to the
  // physical pixel dimensions of the image. If the image is an SVGImage, this
  // does not quite return the intrinsic width/height, but rather a concrete
  // object size resolved using a default object size of 300x150.
  // TODO(fs): Make SVGImages return proper intrinsic width/height.
  IntSize IntrinsicSize(
      RespectImageOrientationEnum should_respect_image_orientation) const;

  void AddObserver(ImageResourceObserver*);
  void RemoveObserver(ImageResourceObserver*);

  // The device pixel ratio we got from the server for this image, or 1.0.
  float DevicePixelRatioHeaderValue() const;
  bool HasDevicePixelRatioHeaderValue() const;

  // Correct the image orientation preference for potentially cross-origin
  // content.
  RespectImageOrientationEnum ForceOrientationIfNecessary(
      RespectImageOrientationEnum default_orientation) const;

  void Trace(Visitor*) const override;

  // Content status and deriving predicates.
  // https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit#heading=h.6cyqmir0f30h
  // Normal transitions:
  //   kNotStarted -> kPending -> kCached|kLoadError|kDecodeError.
  // Additional transitions in multipart images:
  //   kCached -> kLoadError|kDecodeError.
  // Transitions due to revalidation:
  //   kCached -> kPending.
  // Transitions due to reload:
  //   kCached|kLoadError|kDecodeError -> kPending.
  //
  // ImageResourceContent::GetContentStatus() can be different from
  // ImageResource::GetStatus(). Use ImageResourceContent::GetContentStatus().
  ResourceStatus GetContentStatus() const;
  bool IsLoaded() const;
  bool IsLoading() const;
  bool ErrorOccurred() const;
  bool LoadFailedOrCanceled() const;

  // Redirecting methods to Resource.
  const KURL& Url() const;
  base::TimeTicks LoadResponseEnd() const;
  bool IsAccessAllowed() const;
  const ResourceResponse& GetResponse() const;
  base::Optional<ResourceError> GetResourceError() const;
  // DEPRECATED: ImageResourceContents consumers shouldn't need to worry about
  // whether the underlying Resource is being revalidated.
  bool IsCacheValidator() const;

  // For FrameSerializer.
  bool HasCacheControlNoStoreHeader() const;

  void EmulateLoadStartedForInspector(ResourceFetcher*,
                                      const KURL&,
                                      const AtomicString& initiator_name);

  void SetNotRefetchableDataFromDiskCache() {
    is_refetchable_data_from_disk_cache_ = false;
  }

  // The following public methods should be called from ImageResource only.

  // UpdateImage() is the single control point of image content modification
  // from ImageResource that all image updates should call.
  // We clear and/or update images in this single method
  // (controlled by UpdateImageOption) rather than providing separate methods,
  // in order to centralize state changes and
  // not to expose the state in between to ImageResource.
  enum UpdateImageOption {
    // Updates the image (including placeholder and decode error handling
    // and notifying observers) if needed.
    kUpdateImage,

    // Clears the image and then updates the image if needed.
    kClearAndUpdateImage,

    // Clears the image and always notifies observers (without updating).
    kClearImageAndNotifyObservers,
  };
  enum class UpdateImageResult {
    kNoDecodeError,

    // Decode error occurred. Observers are not notified.
    // Only occurs when UpdateImage or ClearAndUpdateImage is specified.
    kShouldDecodeError,
  };
  WARN_UNUSED_RESULT UpdateImageResult UpdateImage(scoped_refptr<SharedBuffer>,
                                                   ResourceStatus,
                                                   UpdateImageOption,
                                                   bool all_data_received,
                                                   bool is_multipart);

  void NotifyStartLoad();
  void DestroyDecodedData();
  void DoResetAnimation();

  void SetImageResourceInfo(ImageResourceInfo*);

  ResourcePriority PriorityFromObservers() const;
  scoped_refptr<const SharedBuffer> ResourceBuffer() const;
  bool ShouldUpdateImageImmediately() const;
  bool HasObservers() const {
    return !observers_.IsEmpty() || !finished_observers_.IsEmpty();
  }
  bool IsRefetchableDataFromDiskCache() const {
    return is_refetchable_data_from_disk_cache_;
  }

  ImageDecoder::CompressionFormat GetCompressionFormat() const;

  // Returns true if the image content is well-compressed (and not full of
  // extraneous metadata). "well-compressed" is determined by comparing the
  // image's compression ratio against a specific value that is defined by an
  // unoptimized image feature policy on |context|.
  bool IsAcceptableCompressionRatio(ExecutionContext& context);

  void LoadDeferredImage(ResourceFetcher* fetcher);

  // Returns whether the resource request has been tagged as an ad.
  bool IsAdResource() const;

  // Records the decoded image type in a UseCounter if the image is a
  // BitmapImage. |use_counter| may be a null pointer.
  void RecordDecodedImageType(UseCounter* use_counter);

 private:
  using CanDeferInvalidation = ImageResourceObserver::CanDeferInvalidation;

  // ImageObserver
  void DecodedSizeChangedTo(const blink::Image*, size_t new_size) override;
  bool ShouldPauseAnimation(const blink::Image*) override;
  void Changed(const blink::Image*) override;
  void AsyncLoadCompleted(const blink::Image*) override;

  scoped_refptr<Image> CreateImage(bool is_multipart);
  void ClearImage();

  enum NotifyFinishOption { kShouldNotifyFinish, kDoNotNotifyFinish };

  void NotifyObservers(NotifyFinishOption, CanDeferInvalidation);
  void HandleObserverFinished(ImageResourceObserver*);
  void UpdateToLoadedContentStatus(ResourceStatus);
  void UpdateImageAnimationPolicy();

  class ProhibitAddRemoveObserverInScope : public base::AutoReset<bool> {
   public:
    ProhibitAddRemoveObserverInScope(const ImageResourceContent* content)
        : AutoReset(&content->is_add_remove_observer_prohibited_, true) {}
  };

  ResourceStatus content_status_ = ResourceStatus::kNotStarted;

  // Indicates if this resource's encoded image data can be purged and refetched
  // from disk cache to save memory usage. See crbug/664437.
  bool is_refetchable_data_from_disk_cache_;

  mutable bool is_add_remove_observer_prohibited_ = false;

  Image::SizeAvailability size_available_ = Image::kSizeUnavailable;

  Member<ImageResourceInfo> info_;

  float device_pixel_ratio_header_value_;
  bool has_device_pixel_ratio_header_value_;

  scoped_refptr<blink::Image> image_;

  HashCountedSet<ImageResourceObserver*> observers_;
  HashCountedSet<ImageResourceObserver*> finished_observers_;

#if DCHECK_IS_ON()
  bool is_update_image_being_called_ = false;
#endif
};

}  // namespace blink

#endif
