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

#pragma once

#include <array>
#include <memory>
#include <queue>

#include <lib/async-loop/cpp/loop.h>
#include <lib/zx/job.h>

#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/strings/string_view.h"

#include "exception_port.h"
#include "io_loop.h"
#include "process.h"
#include "thread.h"

namespace inferior_control {

// Server implements the main loop and handles commands.
//
// NOTE: This class is generally not thread safe. Care must be taken when
// calling methods such as set_current_process() and SetCurrentThread()
// which modify its internal state.
class Server : public Process::Delegate {
 public:
  // Starts the main loop, and returns when the main loop exits.
  // Returns true if the main loop exits cleanly, or false in the case of an
  // error.
  // TODO(armansito): More clearly define the error scenario.
  // TODO(dje): This mightn't need to be virtual, but it provides consistency
  // among the uses.
  virtual bool Run() = 0;

  zx_handle_t job_for_search() const { return job_for_search_.get(); }
  zx_handle_t job_for_launch() const { return job_for_launch_.get(); }

  // Returns a raw pointer to the current inferior. The instance pointed to by
  // the returned pointer is owned by this Server instance and should not be
  // deleted.
  Process* current_process() const { return current_process_.get(); }

  // Sets the current process. This cleans up the current process (if any) and
  // takes ownership of |process|.
  void set_current_process(Process* process) {
    current_process_.reset(process);
  }

  // Returns a raw pointer to the current thread.
  Thread* current_thread() const { return current_thread_.get(); }

  // Assigns the current thread.
  void SetCurrentThread(Thread* thread);

  // Returns a mutable reference to the main message loop. The returned instance
  // is owned by this Server instance and should not be deleted.
  async::Loop& message_loop() { return message_loop_; }

  // Returns a mutable reference to the exception port. The returned instance is
  // owned by this Server instance and should not be deleted.
  ExceptionPort& exception_port() { return exception_port_; }

  // Call this to schedule termination of the server.
  // N.B. The Server will exit its main loop asynchronously so any
  // subsequently posted tasks will be dropped.
  void PostQuitMessageLoop(bool status);

 private:
  // Returns a borrowed handle of the job whose processes we may attach to.
  // If this is ZX_HANDLE_INVALID then we may not attach to any process.
  zx::job job_for_search_;

  // Returns a borrowed handle of the job where processes are launched.
  // This is not necessarily |job_for_search_|, we may be able to attach to
  // any process but not necessarily want to start new processes in the root
  // job itself. If this is ZX_HANDLE_INVALID then starting new processes is
  // not allowed.
  zx::job job_for_launch_;

 protected:
  Server(zx::job job_for_search, zx::job job_for_launch);
  virtual ~Server();

  // Sets the run status and quits the main message loop.
  void QuitMessageLoop(bool status);

  // The current thread under debug. We only keep a weak pointer here, since the
  // instance itself is owned by a Process and may get removed.
  fxl::WeakPtr<Thread> current_thread_;

  // The main loop.
  async::Loop message_loop_;

  // The ExceptionPort used by inferiors to receive exceptions.
  // (This is declared after |message_loop_| since that needs to have been
  // created before this can be initialized).
  ExceptionPort exception_port_;

  // Strong pointer to the current inferior process that is being debugged.
  // NOTE: This must be declared after |exception_port_| above, since the
  // process may do work in its destructor to detach itself from
  // |exception_port_|.
  std::unique_ptr<Process> current_process_;

  // Stores the global error state. This is used to determine the return value
  // for "Run()" when |message_loop_| exits.
  bool run_status_;

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(Server);
};

// Same as Server, but provides I/O support.
// An example use-case is debugserver for gdb.
class ServerWithIO : public Server, public IOLoop::Delegate {
 protected:
  ServerWithIO(zx::job job_for_search, zx::job job_for_launch);
  virtual ~ServerWithIO();

  // The IOLoop used for blocking I/O operations over |client_sock_|.
  // |message_loop_| and |client_sock_| both MUST outlive |io_loop_|. We take
  // care to clean it up in the destructor.
  std::unique_ptr<IOLoop> io_loop_;

  // File descriptor for the socket (or terminal) used for communication.
  // TODO(dje): Rename from *sock* after things are working.
  fxl::UniqueFD client_sock_;
};

}  // namespace inferior_control
