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

#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_H_

#include <list>
#include <memory>
#include <string>
#include <type_traits>

#include "base/containers/flat_map.h"
#include "base/containers/span.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "content/browser/devtools/protocol/protocol.h"
#include "content/public/browser/devtools_agent_host_client_channel.h"
#include "content/public/browser/devtools_external_agent_proxy.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h"

namespace content {

class DevToolsAgentHostClient;
class DevToolsAgentHostImpl;
class DevToolsExternalAgentProxyDelegate;

namespace protocol {
class DevToolsDomainHandler;
class AuditsHandler;
class DOMHandler;
class DeviceOrientationHandler;
class EmulationHandler;
class InputHandler;
class InspectorHandler;
class IOHandler;
class OverlayHandler;
class NetworkHandler;
class FetchHandler;
class StorageHandler;
class TargetHandler;
class PageHandler;
class TracingHandler;
class LogHandler;
class WebAuthnHandler;
}

class DevToolsSession : public protocol::FrontendChannel,
                        public blink::mojom::DevToolsSessionHost,
                        public DevToolsExternalAgentProxy,
                        public content::DevToolsAgentHostClientChannel {
 public:
  // For sessions attached to the Tab target, the mode is set to TabTarget.
  // For other sessions, the mode is inherited from the parent.
  // This is used as an indication that the client has opted in into using
  // tab targets and lets backend use the new logic of target discovery:
  //  - auto-attach on frame targets will not auto-attach subframes (these
  //      will be instead attached to the Tab targets)
  //  - certain features that depend on MPArch support will not be disabled
  //      (BFCache, Prerender)
  enum class Mode {
    kSupportsTabTarget,
    kDoesNotSupportTabTarget,
  };

  class ChildObserver : public base::CheckedObserver {
   public:
    virtual void SessionAttached(DevToolsSession& session) = 0;
  };

  // For root sessions (see also private constructor for children).
  DevToolsSession(DevToolsAgentHostClient* client, Mode mode);
  ~DevToolsSession() override;

  void SetAgentHost(DevToolsAgentHostImpl* agent_host);
  void SetRuntimeResumeCallback(base::OnceClosure runtime_resume);
  bool IsWaitingForDebuggerOnStart() const;
  void Dispose();

  // content::DevToolsAgentHostClientChannel implementation.
  content::DevToolsAgentHost* GetAgentHost() override;
  content::DevToolsAgentHostClient* GetClient() override;

  DevToolsSession* GetRootSession();

  // Browser-only sessions do not talk to mojom::DevToolsAgent, but instead
  // handle all protocol messages locally in the browser process.
  void SetBrowserOnly(bool browser_only);
  template <typename Handler, typename... Args>
  Handler* CreateAndAddHandler(Args&&... args) {
    if (!IsDomainAvailableToUntrustedClient<Handler>() &&
        !client_->IsTrusted()) {
      return nullptr;
    }
    auto handler = std::make_unique<Handler>(std::forward<Args>(args)...);
    Handler* handler_ptr = handler.get();
    AddHandler(std::move(handler));
    return handler_ptr;
  }

  void TurnIntoExternalProxy(DevToolsExternalAgentProxyDelegate* delegate);

  void AttachToAgent(blink::mojom::DevToolsAgent* agent,
                     bool force_using_io_session);
  void DispatchProtocolMessage(base::span<const uint8_t> message);
  void SuspendSendingMessagesToAgent();
  void ResumeSendingMessagesToAgent();
  void ClearPendingMessages(bool did_crash);

  using HandlersMap =
      base::flat_map<std::string,
                     std::unique_ptr<protocol::DevToolsDomainHandler>>;
  HandlersMap& handlers() { return handlers_; }

  DevToolsSession* AttachChildSession(const std::string& session_id,
                                      DevToolsAgentHostImpl* agent_host,
                                      DevToolsAgentHostClient* client,
                                      Mode mode,
                                      base::OnceClosure resume_callback);
  void DetachChildSession(const std::string& session_id);
  bool HasChildSession(const std::string& session_id);
  Mode session_mode() const { return mode_; }

  void AddObserver(ChildObserver* obs);
  void RemoveObserver(ChildObserver* obs);

  base::RepeatingCallback<void(std::string)> MakePrepareForReloadCallback() {
    return base::BindRepeating(&DevToolsSession::PrepareForReload,
                               base::Unretained(this));
  }

  void EnableDurableMessageCollector(
      const base::UnguessableToken& devtools_token,
      network::mojom::NetworkDurableMessageConfigPtr config,
      base::OnceClosure callback);
  void DisableDurableMessageCollectorForProfile(
      const base::UnguessableToken& devtools_token,
      base::OnceClosure callback);
  network::mojom::DurableMessageCollector* MaybeGetDurableMessageCollector();

 private:
  struct PendingMessage {
    int call_id;
    std::string method;
    std::vector<uint8_t> payload;

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

    PendingMessage(PendingMessage&&);
    PendingMessage(int call_id,
                   crdtp::span<uint8_t> method,
                   crdtp::span<uint8_t> payload);
    ~PendingMessage();
  };

  // For child sessions.
  DevToolsSession(DevToolsAgentHostClient* client,
                  const std::string& session_id,
                  DevToolsSession* parent,
                  Mode mode);

  void MojoConnectionDestroyed();
  void DispatchToAgent(const PendingMessage& message);
  void HandleCommand(base::span<const uint8_t> message);
  void HandleCommandInternal(crdtp::Dispatchable dispatchable,
                             base::span<const uint8_t> message);
  void DispatchProtocolMessageInternal(crdtp::Dispatchable dispatchable,
                                       base::span<const uint8_t> message);

  // protocol::FrontendChannel implementation.
  void SendProtocolResponse(
      int call_id,
      std::unique_ptr<protocol::Serializable> message) override;
  void SendProtocolNotification(
      std::unique_ptr<protocol::Serializable> message) override;
  void FlushProtocolNotifications() override;
  void FallThrough(int call_id,
                   crdtp::span<uint8_t> method,
                   crdtp::span<uint8_t> message) override;

  // content::DevToolsAgentHostClientChannel implementation.
  void DispatchProtocolMessageToClient(std::vector<uint8_t> message) override;

  // blink::mojom::DevToolsSessionHost implementation.
  void DispatchProtocolResponse(
      blink::mojom::DevToolsMessagePtr message,
      int call_id,
      blink::mojom::DevToolsSessionStatePtr updates) override;
  void DispatchProtocolNotification(
      blink::mojom::DevToolsMessagePtr message,
      blink::mojom::DevToolsSessionStatePtr updates) override;

  // DevToolsExternalAgentProxy implementation.
  void DispatchOnClientHost(base::span<const uint8_t> message) override;
  void ConnectionClosed() override;

  // Merges the |updates| received from the renderer into session_state_cookie_.
  void ApplySessionStateUpdates(blink::mojom::DevToolsSessionStatePtr updates);

  template <typename T>
  bool IsDomainAvailableToUntrustedClient() {
    return std::disjunction_v<
        std::is_same<T, protocol::AuditsHandler>,
        std::is_same<T, protocol::DOMHandler>,
        std::is_same<T, protocol::DeviceOrientationHandler>,
        std::is_same<T, protocol::EmulationHandler>,
        std::is_same<T, protocol::InputHandler>,
        std::is_same<T, protocol::InspectorHandler>,
        std::is_same<T, protocol::IOHandler>,
        std::is_same<T, protocol::OverlayHandler>,
        std::is_same<T, protocol::NetworkHandler>,
        std::is_same<T, protocol::FetchHandler>,
        std::is_same<T, protocol::StorageHandler>,
        std::is_same<T, protocol::TargetHandler>,
        std::is_same<T, protocol::PageHandler>,
        std::is_same<T, protocol::TracingHandler>,
        std::is_same<T, protocol::LogHandler>,
        std::is_same<T, protocol::WebAuthnHandler>>;
  }
  void AddHandler(std::unique_ptr<protocol::DevToolsDomainHandler> handler);
  void PrepareForReload(std::string script_to_evaluate_on_load);

  const raw_ptr<DevToolsAgentHostClient> client_;
  const raw_ptr<DevToolsSession> root_session_ = nullptr;
  const std::string session_id_;  // empty if this is the root session.
  const Mode mode_;

  mojo::AssociatedReceiver<blink::mojom::DevToolsSessionHost> receiver_{this};
  mojo::AssociatedRemote<blink::mojom::DevToolsSession> session_;
  mojo::Remote<blink::mojom::DevToolsSession> io_session_;
  bool use_io_session_{false};
  raw_ptr<DevToolsAgentHostImpl> agent_host_ = nullptr;
  bool browser_only_ = false;
  HandlersMap handlers_;
  std::unique_ptr<protocol::UberDispatcher> dispatcher_{
      new protocol::UberDispatcher(this)};

  bool suspended_sending_messages_to_agent_ = false;

  // Messages that were sent to the agent or queued after suspending.
  std::list<PendingMessage> pending_messages_;
  // Pending messages that were sent and are thus waiting for a response.
  base::flat_map<int, std::list<PendingMessage>::iterator>
      waiting_for_response_;

  // |session_state_cookie_| always corresponds to a state before
  // any of the waiting for response messages have been handled.
  // |session_state_cookie_| is nullptr before first attach.
  blink::mojom::DevToolsSessionStatePtr session_state_cookie_;
  std::string script_to_evaluate_on_load_;

  base::flat_map<std::string, raw_ptr<DevToolsSession, CtnExperimental>>
      child_sessions_;
  base::OnceClosure runtime_resume_;
  raw_ptr<DevToolsExternalAgentProxyDelegate> proxy_delegate_ = nullptr;
  base::ObserverList<ChildObserver, true, false> child_observers_;
  mojo::Remote<network::mojom::DurableMessageCollector>
      durable_message_collector_;

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

}  // namespace content

#endif  // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_H_
