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

#ifndef STORAGE_BROWSER_BLOB_BLOB_READER_H_
#define STORAGE_BROWSER_BLOB_BLOB_READER_H_

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <memory>
#include <vector>

#include "base/component_export.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "components/file_access/scoped_file_access.h"
#include "components/file_access/scoped_file_access_delegate.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/completion_once_callback.h"
#include "services/network/public/cpp/data_pipe_to_source_stream.h"
#include "storage/browser/blob/blob_storage_constants.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

class GURL;

namespace base {
class FilePath;
class TaskRunner;
class Time;
}

namespace net {
class DrainableIOBuffer;
class IOBuffer;
}

namespace storage {
class BlobDataItem;
class BlobDataHandle;
class BlobDataSnapshot;
class FileStreamReader;

// The blob reader is used to read a blob.  This can only be used in the browser
// process, and we need to be on the IO thread.
//  * There can only be one read happening at a time per reader.
//  * If a status of Status::NET_ERROR is returned, that means there was an
//    error and the net_error() variable contains the error code.
// Use a BlobDataHandle to create an instance.
//
// For more information on how to read Blobs in your specific situation, see:
// https://chromium.googlesource.com/chromium/src/+/HEAD/storage/browser/blob/README.md#how-to-use-blobs-browser_side-accessing-reading
class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader {
 public:
  class COMPONENT_EXPORT(STORAGE_BROWSER) FileStreamReaderProvider {
   public:
    virtual ~FileStreamReaderProvider();

    virtual std::unique_ptr<FileStreamReader> CreateForLocalFile(
        base::TaskRunner* task_runner,
        const base::FilePath& file_path,
        int64_t initial_offset,
        const base::Time& expected_modification_time) = 0;

    virtual std::unique_ptr<FileStreamReader> CreateFileStreamReader(
        const GURL& filesystem_url,
        int64_t offset,
        int64_t max_bytes_to_read,
        const base::Time& expected_modification_time) = 0;
  };
  enum class Status { NET_ERROR, IO_PENDING, DONE };
  using StatusCallback = base::OnceCallback<void(Status)>;

  BlobReader(const BlobReader&) = delete;
  BlobReader& operator=(const BlobReader&) = delete;

  virtual ~BlobReader();

  // This calculates the total size of the blob, and initializes the reading
  // cursor.
  //  * This should only be called once per reader.
  //  * Status::Done means that the total_size() value is populated and you can
  //    continue to SetReadRange or Read.
  //  * The 'done' callback is only called if Status::IO_PENDING is returned.
  //    The callback value contains the error code or net::OK. Please use the
  //    total_size() value to query the blob size, as it's uint64_t.
  Status CalculateSize(net::CompletionOnceCallback done);

  // Returns true when the blob has side data. CalculateSize must be called
  // beforehand. Currently side data is supported only for single readable
  // DataHandle entry blob. So it returns false when the blob has more than
  // single data item. This side data is used to pass the V8 code cache which is
  // stored as a side stream in the CacheStorage to the renderer.
  // (crbug.com/581613).  This will still return true even after TakeSideData
  // has been called.
  bool has_side_data() const;

  // Reads the side data of the blob. CalculateSize must be called beforehand.
  // * Always calls the StatusCallback when the side data has been read.
  // * This may be done synchronously or asynchronously.
  // * The done callback will be called with Status::DONE or Status::NET_ERROR.
  // * If the callback returns NET_ERROR, net_error() will have the value.
  // Currently side data is supported only for single readable DataHandle entry
  // blob.
  void ReadSideData(StatusCallback done);

  // Passes the side data (if any) from ReadSideData() to the caller.
  absl::optional<mojo_base::BigBuffer> TakeSideData();

  // Used to set the read position.
  // * This should be called after CalculateSize and before Read.
  // * Range can only be set once.
  Status SetReadRange(uint64_t position, uint64_t length);

  // Reads a portion of the data.
  // * CalculateSize (and optionally SetReadRange) must be called beforehand.
  // * bytes_read is populated only if Status::DONE is returned. Otherwise the
  //   bytes read (or error code) is populated in the 'done' callback.
  // * The done callback is only called if Status::IO_PENDING is returned.
  // * This method can be called multiple times. A bytes_read value (either from
  //   the callback for Status::IO_PENDING or the bytes_read value for
  //   Status::DONE) of 0 means we're finished reading.
  Status Read(net::IOBuffer* buffer,
              size_t dest_size,
              int* bytes_read,
              net::CompletionOnceCallback done);

  // Returns if this reader contains a single MojoDataItem.  If so,
  // ReadSingleMojoDataItem can be called instead of multiple Reads as an
  // optimized path.  This can only be called after CalculateSize.
  bool IsSingleMojoDataItem() const;
  void ReadSingleMojoDataItem(mojo::ScopedDataPipeProducerHandle producer,
                              net::CompletionOnceCallback done);

  // Kills reading and invalidates all callbacks. The reader cannot be used
  // after this call.
  void Kill();

  // Returns if all of the blob's items are in memory. Should only be called
  // after CalculateSize.
  bool IsInMemory() const;

  // Returns the remaining bytes to be read in the blob. This is populated
  // after CalculateSize, and is modified by SetReadRange.
  uint64_t remaining_bytes() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return remaining_bytes_;
  }

  // Returns the net error code if there was an error. Defaults to net::OK.
  int net_error() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return net_error_;
  }

  // Returns the total size of the blob. This is populated after CalculateSize
  // is called.
  uint64_t total_size() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    DCHECK(total_size_calculated_);
    return total_size_;
  }

 protected:
  friend class BlobDataHandle;
  friend class BlobReaderTest;
  FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, HandleBeforeAsyncCancel);
  FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, ReadFromIncompleteBlob);

  explicit BlobReader(const BlobDataHandle* blob_handle);

  bool total_size_calculated() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return total_size_calculated_;
  }

  void SetFileStreamProviderForTesting(
      std::unique_ptr<FileStreamReaderProvider> file_stream_provider) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    file_stream_provider_for_testing_ = std::move(file_stream_provider);
  }

 private:
  Status ReportError(int net_error);
  void InvalidateCallbacksAndDone(int net_error,
                                  net::CompletionOnceCallback done);

  void AsyncCalculateSize(net::CompletionOnceCallback done, BlobStatus status);
  // If this returns Status::IO_PENDING, it will take ownership of the callback
  // pointed at by |done| and call it when complete. |done| will not be
  // modified, otherwise.
  Status CalculateSizeImpl(net::CompletionOnceCallback* done);
  bool AddItemLength(size_t index, uint64_t length);
  bool ResolveFileItemLength(const BlobDataItem& item,
                             int64_t total_length,
                             uint64_t* output_length);
  void DidGetFileItemLength(size_t index, int64_t result);
  void DidCountSize();

  // For reading the blob.
  // Returns if we're done, PENDING_IO if we're waiting on async.
  Status ReadLoop(int* bytes_read);
  // Called from asynchronously called methods to continue the read loop.
  void ContinueAsyncReadLoop();
  // PENDING_IO means we're waiting on async.
  Status ReadItem();
  void AdvanceItem();
  void AdvanceBytesRead(int result);
  void ReadBytesItem(const BlobDataItem& item, int bytes_to_read);
  BlobReader::Status ReadFileItem(
      FileStreamReader* reader,
      int bytes_to_read,
      file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
          file_access);
  void DidReadFile(int result);
  void DeleteItemReaders();
  Status ReadReadableDataHandle(const BlobDataItem& item, int bytes_to_read);
  void DidReadReadableDataHandle(int result);
  void DidReadItem(int result);
  void DidReadSideData(StatusCallback done,
                       int expected_size,
                       int result,
                       mojo_base::BigBuffer data);
  int ComputeBytesToRead() const;
  int BytesReadCompleted();

  // Returns a FileStreamReader for a blob item at |index|.
  // If the item at |index| is not of type kFile this returns nullptr.
  FileStreamReader* GetOrCreateFileReaderAtIndex(size_t index);
  // If the reader is null, then this basically performs a delete operation.
  void SetFileReaderAtIndex(size_t index,
                            std::unique_ptr<FileStreamReader> reader);
  // Creates a FileStreamReader for the item with additional_offset.
  std::unique_ptr<FileStreamReader> CreateFileStreamReader(
      const BlobDataItem& item,
      uint64_t additional_offset);
  // Returns a DataPipeToSourceStream for a blob item at |Index|.
  // If the item at |index| is not of type kReadableDataHandle this returns
  // nullptr.
  network::DataPipeToSourceStream* GetOrCreateDataPipeAtIndex(size_t index);
  void SetDataPipeAtIndex(
      size_t index,
      std::unique_ptr<network::DataPipeToSourceStream> pipe);
  std::unique_ptr<network::DataPipeToSourceStream> CreateDataPipe(
      const BlobDataItem& item,
      uint64_t additional_offset);

  void RecordBytesReadFromDataHandle(int item_index, int result);

  std::unique_ptr<BlobDataHandle> blob_handle_;
  std::unique_ptr<BlobDataSnapshot> blob_data_;
  std::unique_ptr<FileStreamReaderProvider> file_stream_provider_for_testing_;
  scoped_refptr<base::TaskRunner> file_task_runner_;
  absl::optional<mojo_base::BigBuffer> side_data_;

  int net_error_;
  bool item_list_populated_ = false;
  std::vector<uint64_t> item_length_list_;

  scoped_refptr<net::DrainableIOBuffer> read_buf_;

  bool total_size_calculated_ = false;
  uint64_t total_size_ = 0;
  uint64_t remaining_bytes_ = 0;
  size_t pending_get_file_info_count_ = 0;
  std::map<size_t, std::unique_ptr<FileStreamReader>> index_to_reader_;
  std::map<size_t, std::unique_ptr<network::DataPipeToSourceStream>>
      index_to_pipe_;
  size_t current_item_index_ = 0;
  uint64_t current_item_offset_ = 0;

  bool io_pending_ = false;

  net::CompletionOnceCallback size_callback_;
  net::CompletionOnceCallback read_callback_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<BlobReader> weak_factory_{this};
};

}  // namespace storage
#endif  // STORAGE_BROWSER_BLOB_BLOB_READER_H_
