// 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 <memory>

#include <lib/async-loop/cpp/loop.h>
#include <src/lib/fxl/macros.h>
#include <src/lib/fxl/strings/string_view.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/job.h>
#include <src/lib/files/unique_fd.h>

#include "garnet/lib/process/process_builder.h"

#include "delegate.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 client operations and inferior
// events (exceptions, etc).
//
// TODO(dje): It might be useful to separate out |Delegate| here.
// It is used as a "mixin" to simplify early clients.
//
// 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 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_; }

  // Accessor for the exception port's handle.
  // TODO(PT-105): Delete when exceptions have handles themselves.
  zx_handle_t exception_port_handle() const { return exception_port_.handle(); }

  // Utility to create a new inferior via |process::ProcessBuilder|.
  // Returns false if there is an error.
  // |*out_builder| is returned in case the caller wants to add anything
  // further to the new process. A typical example is to call
  // |builder->CloneAll()| as no cloning is done yet. |*out_builder| is
  // intended to be passed to |Process::InitializeFromBuilder|.
  // TODO(dje): InferiorManager class to manage multiple inferiors, and
  // creating them.
  bool CreateProcessViaBuilder(
      const std::string& path, const debugger_utils::Argv& argv,
      std::unique_ptr<process::ProcessBuilder>* out_builder);

  // Return a handle to a running process that can be used for debugging.
  // Returns an invalid object if the process is not found or the handle is
  // unobtainable.
  // |pid| is looked up via |job_to_search()|.
  zx::process FindProcess(zx_koid_t pid);

  // 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);

  // Register an async-wait for |thread| on the exception port loop.
  void WaitAsync(Thread* thread);

 private:
  void OnProcessException(const zx_port_packet_t& packet);
  void OnProcessSignal(const zx_port_packet_t& packet);

  // 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_;

  // The services to pass to processes created with
  // |CreateProcessViaBuilder()|.
  std::shared_ptr<sys::ServiceDirectory> services_;

 protected:
  Server(zx::job job_for_search, zx::job job_for_launch,
         std::shared_ptr<sys::ServiceDirectory> services);

  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,
               std::shared_ptr<sys::ServiceDirectory> services);
  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
