// Copyright 2015 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 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/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.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);

  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);
  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_
