// 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_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_

#include <memory>

#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"

namespace blink {

class ClassicPendingScript;
class ScriptResource;
class ScriptState;
class Settings;
class SourceStream;

// ScriptStreamer streams incomplete script data to V8 so that it can be parsed
// while it's loaded. ClassicPendingScript holds a reference to ScriptStreamer.
// At the moment, ScriptStreamer is only used for parser blocking scripts; this
// means that the Document stays stable and no other scripts are executing
// while we're streaming. It is possible, though, that Document and the
// ClassicPendingScript are destroyed while the streaming is in progress, and
// ScriptStreamer handles it gracefully.
class CORE_EXPORT ScriptStreamer final
    : public GarbageCollectedFinalized<ScriptStreamer> {
  WTF_MAKE_NONCOPYABLE(ScriptStreamer);

 public:
  // For tracking why some scripts are not streamed. Not streaming is part of
  // normal operation (e.g., script already loaded, script too small) and
  // doesn't necessarily indicate a failure.
  enum NotStreamingReason {
    kAlreadyLoaded,  // DEPRECATED
    kNotHTTP,
    kReload,
    kContextNotValid,
    kEncodingNotSupported,
    kThreadBusy,
    kV8CannotStream,
    kScriptTooSmall,
    kNoResourceBuffer,
    kHasCodeCache,
    kStreamerNotReadyOnGetSource,
    kInlineScript,
    kDidntTryToStartStreaming,

    // Pseudo values that should never be seen in reported metrics
    kCount,
    kInvalid = -1,
  };

  ~ScriptStreamer();
  void Trace(blink::Visitor*);

  // Launches a task (on a background thread) which will stream the given
  // ClassicPendingScript into V8 as it loads.
  static void StartStreaming(ClassicPendingScript*,
                             Settings*,
                             ScriptState*,
                             scoped_refptr<base::SingleThreadTaskRunner>,
                             NotStreamingReason* not_streaming_reason);

  // Returns false if we cannot stream the given encoding.
  static bool ConvertEncoding(const char* encoding_name,
                              v8::ScriptCompiler::StreamedSource::Encoding*);

  bool IsFinished() const;           // Has loading & streaming finished?
  bool IsStreamingFinished() const;  // Has streaming finished?

  v8::ScriptCompiler::StreamedSource* Source() { return source_.get(); }

  // Called when the script is not needed any more (e.g., loading was
  // cancelled). After calling cancel, ClassicPendingScript can drop its
  // reference to ScriptStreamer, and ScriptStreamer takes care of eventually
  // deleting itself (after the V8 side has finished too).
  void Cancel();

  // When the streaming is suppressed, the data is not given to V8, but
  // ScriptStreamer still watches the resource load and notifies the upper
  // layers when loading is finished. It is used in situations when we have
  // started streaming but then we detect we don't want to stream (e.g., when
  // we have the code cache for the script) and we still want to parse and
  // execute it when it has finished loading.
  void SuppressStreaming(NotStreamingReason reason);
  bool StreamingSuppressed() const {
    DCHECK(!streaming_suppressed_ || suppressed_reason_ != kInvalid);
    return streaming_suppressed_;
  }
  NotStreamingReason StreamingSuppressedReason() const {
    DCHECK(streaming_suppressed_ || suppressed_reason_ == kInvalid);
    return suppressed_reason_;
  }

  // Called by ClassicPendingScript when data arrives from the network.
  void NotifyAppendData(ScriptResource*);
  void NotifyFinished();

  // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
  // has processed it.
  void StreamingCompleteOnBackgroundThread();

  const String& ScriptURLString() const { return script_url_string_; }
  unsigned long ScriptResourceIdentifier() const {
    return script_resource_identifier_;
  }

  static void SetSmallScriptThresholdForTesting(size_t threshold) {
    small_script_threshold_ = threshold;
  }

 private:
  // Scripts whose first data chunk is smaller than this constant won't be
  // streamed. Non-const for testing.
  static size_t small_script_threshold_;

  ScriptStreamer(ClassicPendingScript*,
                 ScriptState*,
                 v8::ScriptCompiler::CompileOptions,
                 scoped_refptr<base::SingleThreadTaskRunner>);

  void StreamingComplete();
  void NotifyFinishedToClient();

  Member<ClassicPendingScript> pending_script_;
  // Whether ScriptStreamer is detached from the Resource. In those cases, the
  // script data is not needed any more, and the client won't get notified
  // when the loading and streaming are done.
  bool detached_;

  SourceStream* stream_;
  std::unique_ptr<v8::ScriptCompiler::StreamedSource> source_;
  bool loading_finished_;  // Whether loading from the network is done.
  bool parsing_finished_;  // Whether the V8 side processing is done.
  // Whether we have received enough data to start the streaming.
  bool have_enough_data_for_streaming_;

  // Whether the script source code should be retrieved from the Resource
  // instead of the ScriptStreamer.
  bool streaming_suppressed_;
  NotStreamingReason suppressed_reason_;

  // What kind of cached data V8 produces during streaming.
  v8::ScriptCompiler::CompileOptions compile_options_;

  Member<ScriptState> script_state_;

  // Keep the script URL string for event tracing.
  const String script_url_string_;

  // Keep the script resource dentifier for event tracing.
  const unsigned long script_resource_identifier_;

  // Encoding of the streamed script. Saved for sanity checking purposes.
  v8::ScriptCompiler::StreamedSource::Encoding encoding_;

  scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
