// 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 COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_
#define COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_

#include <string_view>
#include <vector>

#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "components/ui_devtools/devtools_client.h"
#include "components/ui_devtools/devtools_export.h"
#include "components/ui_devtools/dom.h"
#include "components/ui_devtools/forward.h"
#include "components/ui_devtools/protocol.h"
#include "net/server/http_server_request_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace base {
class SingleThreadTaskRunner;
}

namespace ui_devtools {

class TracingAgent;

class UI_DEVTOOLS_EXPORT UiDevToolsServer {
 public:
  // Network tags to be used for the UI devtools servers.
  static const net::NetworkTrafficAnnotationTag kUIDevtoolsServerTag;

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

  ~UiDevToolsServer();

  // Returns an empty unique_ptr if ui devtools flag isn't enabled or if a
  // server instance has already been created. All network activity is performed
  // on `io_thread_task_runner`, which must run tasks on a thread with an IO
  // message pump. All other work is done on the thread the UiDevToolsServer is
  // created on. If `port` is 0, the server will choose an available port. If
  // `port` is 0 and `active_port_output_directory` is present, the server will
  // write the chosen port to `kUIDevToolsActivePortFileName` on
  // `active_port_output_directory`.
  static std::unique_ptr<UiDevToolsServer> CreateForViews(
      scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
      int port,
      const base::FilePath& active_port_output_directory = base::FilePath());


  // Returns a list of attached UiDevToolsClient name + URL
  using NameUrlPair = std::pair<std::string, std::string>;
  static std::vector<NameUrlPair> GetClientNamesAndUrls();

  // Returns true if UI Devtools is enabled by the given commandline switch.
  static bool IsUiDevToolsEnabled(const char* enable_devtools_flag);

  // Returns the port number specified by a command line flag. If a number is
  // not specified as a command line argument, returns the |default_port|.
  static int GetUiDevToolsPort(const char* enable_devtools_flag,
                               int default_port);

  void AttachClient(std::unique_ptr<UiDevToolsClient> client);
  void SendOverWebSocket(int connection_id, std::string_view message);

  int port() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
    return port_;
  }

  TracingAgent* tracing_agent() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
    return tracing_agent_;
  }

  void set_tracing_agent(TracingAgent* agent) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
    tracing_agent_ = agent;
  }

  // Sets the callback which will be invoked when the session is closed.
  // Marks as a const function so it can be called after the server is set up
  // and used as a constant instance.
  void SetOnSessionEnded(base::OnceClosure callback) const;
  // Sets a callback that tests can use to wait for the server to be ready to
  // accept connections.
  void SetOnSocketConnectedForTesting(base::OnceClosure on_socket_connected);
  // Sets a callback that tests can use to wait for a client to connect.
  void SetOnClientConnectedForTesting(base::OnceClosure on_client_connected);
  // Allows calling OnWebSocketRequest() with unexpected connection IDs for
  // tests, bypassing the HttpServer.
  void OnWebSocketRequestForTesting(int connection_id,
                                    net::HttpServerRequestInfo info);

 private:
  // Class that owns the ServerSocket and, after creation on the main thread,
  // may only subsequently be used on the IO thread. The class is needed because
  // HttpServers must live on an IO thread. This class contains all state that's
  // read or written on the IO thread, to avoid UAF's on teardown. When the
  // UiDevToolsServer server is destroyed, a task is posted to destroy the
  // IOThreadData, but that task could still be run after the UiDevToolsServer
  // is fully torn down.
  //
  // Because of this pattern, it's always safe to post messages to the IO thread
  // to dereference the IOThreadData from the UiDevToolsServer assuming this
  // class will still be valid, but tasks it posts back to the main thread to
  // dereference the UiDevToolsServer must use weak pointers.
  class IOThreadData;

  UiDevToolsServer(
      scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
      int port,
      const net::NetworkTrafficAnnotationTag tag,
      const base::FilePath& active_port_output_directory);

  // Invoked on the IO thread, initializes `server_` and starts listening for
  // connections on `port`.
  void MakeServer(int port);

  // Invoked on the main thread. Called by MakeServer via a post task.
  void ServerCreated(int port);

  // These mirror the corresponding HttpServer methods.
  void OnWebSocketRequest(int connection_id, net::HttpServerRequestInfo info);
  void OnWebSocketMessage(int connection_id, std::string data);
  void OnClose(int connection_id);

  using ClientsList = std::vector<std::unique_ptr<UiDevToolsClient>>;
  using ConnectionsMap =
      std::map<uint32_t, raw_ptr<UiDevToolsClient, CtnExperimental>>;
  ClientsList clients_ GUARDED_BY_CONTEXT(main_sequence_);
  ConnectionsMap connections_ GUARDED_BY_CONTEXT(main_sequence_);

  const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;

  // The port the devtools server listens on.
  int port_ GUARDED_BY_CONTEXT(main_sequence_);

  raw_ptr<TracingAgent> tracing_agent_ GUARDED_BY_CONTEXT(main_sequence_) =
      nullptr;

  // Invoked when the server doesn't have any live connections.
  mutable base::OnceClosure on_session_ended_
      GUARDED_BY_CONTEXT(main_sequence_);

  // Set once the server has been started.
  bool connected_ GUARDED_BY_CONTEXT(main_sequence_) = false;

  // Invoked once the server has been started.
  base::OnceClosure on_socket_connected_ GUARDED_BY_CONTEXT(main_sequence_);

  // Invoked when a client connects.
  base::OnceClosure on_client_connected_ GUARDED_BY_CONTEXT(main_sequence_);

  // The server (owned by Chrome for now)
  static UiDevToolsServer* devtools_server_;

  std::unique_ptr<IOThreadData> io_thread_data_;

  SEQUENCE_CHECKER(main_sequence_);
  base::WeakPtrFactory<UiDevToolsServer> weak_ptr_factory_{this};
};

}  // namespace ui_devtools

#endif  // COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_
