// Copyright 2014 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_FETCH_BODY_STREAM_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_H_

#include <memory>
#include "base/types/pass_key.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/chunked_data_pipe_getter.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h"
#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"

namespace blink {

class BytesUploader;
class EncodedFormData;
class ExceptionState;
class ReadableStream;
class ScriptState;
class ScriptCachedMetadataHandler;

class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
                                           public BytesConsumer::Client {
 public:
  using PassKey = base::PassKey<BodyStreamBuffer>;

  // Create a BodyStreamBuffer for |consumer|.
  // |consumer| must not have a client.
  // This function must be called after entering an appropriate V8 context.
  // |signal| should be non-null when this BodyStreamBuffer is associated with a
  // Response that was created by fetch().
  static BodyStreamBuffer* Create(
      ScriptState*,
      BytesConsumer* consumer,
      AbortSignal* signal,
      ScriptCachedMetadataHandler* cached_metadata_handler,
      scoped_refptr<BlobDataHandle> side_data_blob = nullptr);

  // Create() should be used instead of calling this constructor directly.
  BodyStreamBuffer(PassKey,
                   ScriptState*,
                   BytesConsumer* consumer,
                   AbortSignal* signal,
                   ScriptCachedMetadataHandler* cached_metadata_handler,
                   scoped_refptr<BlobDataHandle> side_data_blob);

  BodyStreamBuffer(ScriptState*,
                   ReadableStream* stream,
                   ScriptCachedMetadataHandler* cached_metadata_handler,
                   scoped_refptr<BlobDataHandle> side_data_blob = nullptr);

  ReadableStream* Stream() { return stream_; }

  // Callable only when neither locked nor disturbed.
  scoped_refptr<BlobDataHandle> DrainAsBlobDataHandle(
      BytesConsumer::BlobSizePolicy);
  scoped_refptr<EncodedFormData> DrainAsFormData();
  void DrainAsChunkedDataPipeGetter(
      ScriptState*,
      mojo::PendingReceiver<network::mojom::blink::ChunkedDataPipeGetter>);
  void StartLoading(FetchDataLoader*,
                    FetchDataLoader::Client* /* client */,
                    ExceptionState&);
  void Tee(BodyStreamBuffer**, BodyStreamBuffer**, ExceptionState&);

  // UnderlyingSourceBase
  ScriptPromise pull(ScriptState*) override;
  ScriptPromise Cancel(ScriptState*, ScriptValue reason) override;
  bool HasPendingActivity() const override;
  void ContextDestroyed() override;

  // BytesConsumer::Client
  void OnStateChange() override;
  String DebugName() const override { return "BodyStreamBuffer"; }

  bool IsStreamReadable() const;
  bool IsStreamClosed() const;
  bool IsStreamErrored() const;
  bool IsStreamLocked() const;
  bool IsStreamDisturbed() const;

  // Closes the stream if necessary, and then locks and disturbs it. Should not
  // be called if |stream_broken_| is true.
  void CloseAndLockAndDisturb();

  ScriptState* GetScriptState() { return script_state_; }

  bool IsAborted();

  // Returns the ScriptCachedMetadataHandler associated with the contents of
  // this stream. This can return nullptr. Streams' ownership model applies, so
  // this function is expected to be called by the owner of this stream.
  ScriptCachedMetadataHandler* GetCachedMetadataHandler() {
    DCHECK(!IsStreamLocked());
    DCHECK(!IsStreamDisturbed());
    return cached_metadata_handler_;
  }

  // Take the blob representing any side data associated with this body
  // stream.  This must be called before the body is drained or begins
  // loading.
  scoped_refptr<BlobDataHandle> TakeSideDataBlob();
  scoped_refptr<BlobDataHandle> GetSideDataBlobForTest() const {
    return side_data_blob_;
  }

  bool IsMadeFromReadableStream() const { return made_from_readable_stream_; }

  void Trace(Visitor*) const override;

 private:
  class LoaderClient;

  // This method exists to avoid re-entrancy inside the BodyStreamBuffer
  // constructor. It is called by Create(). It should not be called after
  // using the ReadableStream* constructor.
  void Init();

  BytesConsumer* ReleaseHandle(ExceptionState&);
  void Abort();
  void Close();
  void GetError();
  void CancelConsumer();
  void ProcessData();
  void EndLoading();
  void StopLoading();

  Member<ScriptState> script_state_;
  Member<ReadableStream> stream_;
  Member<BytesUploader> stream_uploader_;
  Member<BytesConsumer> consumer_;
  // We need this member to keep it alive while loading.
  Member<FetchDataLoader> loader_;
  // We need this to ensure that we detect that abort has been signalled
  // correctly.
  Member<AbortSignal> signal_;
  // CachedMetadata handler used for loading compiled WASM code.
  Member<ScriptCachedMetadataHandler> cached_metadata_handler_;
  // Additional side data associated with this body stream.  It should only be
  // retained until the body is drained or starts loading.  Client code, such
  // as service workers, can call TakeSideDataBlob() prior to consumption.
  scoped_refptr<BlobDataHandle> side_data_blob_;
  bool stream_needs_more_ = false;
  bool made_from_readable_stream_;
  bool in_process_data_ = false;

  // TODO(ricea): Remove remaining uses of |stream_broken_|.
  bool stream_broken_ = false;

  DISALLOW_COPY_AND_ASSIGN(BodyStreamBuffer);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_H_
