// Copyright 2018 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.

#ifndef SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_JOB_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_JOB_H_

#include <memory>
#include <set>
#include <vector>

#include "src/developer/debug/debug_agent/job_handle.h"
#include "src/developer/debug/debug_agent/process_handle.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/shared/regex.h"
#include "src/developer/debug/shared/zircon_exception_watcher.h"
#include "src/lib/fxl/macros.h"

namespace debug_agent {

class DebuggedJob;

class ProcessStartHandler {
 public:
  // During this call the thread will be stopped on the "start" exception and this exception will
  // be cleared when this call completes. If the implementation wants to keep the thread suspended,
  // it should manually suspend.
  //
  // The matching filter is passed in case the handler is tracking from which this event comes from.
  virtual void OnProcessStart(const std::string& filter,
                              std::unique_ptr<ProcessHandle> process) = 0;
};

class DebuggedJob : public debug_ipc::ZirconExceptionWatcher {
 public:
  struct FilterInfo {
    std::string filter;
    // Filter used to compare against this filter. We keep it around so we don't need to recompile
    // it every time we compare against a new process.
    debug_ipc::Regex regex;

    bool Matches(const std::string& proc_name);
  };

  // Declare a set of processes, unique-ified by koid.
  struct CompareProcessHandleByKoid {
    bool operator()(const std::unique_ptr<ProcessHandle>& left,
                    const std::unique_ptr<ProcessHandle>& right) const {
      return left->GetKoid() < right->GetKoid();
    }
  };
  using ProcessHandleSetByKoid =
      std::set<std::unique_ptr<ProcessHandle>, CompareProcessHandleByKoid>;

  // Caller must call Init immediately after construction and delete the object if that fails.
  // The ProcessStartHandler pointer must outlive this class.
  DebuggedJob(ProcessStartHandler* handler, std::unique_ptr<JobHandle> job_handle);
  virtual ~DebuggedJob();

  const JobHandle& job_handle() const { return *job_handle_; }
  JobHandle& job_handle() { return *job_handle_; }

  zx_koid_t koid() const { return job_handle_->GetKoid(); }

  // Returns the set of processes that matches any of the |filters|.
  ProcessHandleSetByKoid SetFilters(std::vector<std::string> filters);

  void AppendFilter(std::string filter);
  const std::vector<FilterInfo>& filters() const { return filters_; }

  // Returns ZX_OK on success. On failure, the object may not be used further.
  zx_status_t Init();

 private:
  // ZirconExceptionWatcher implementation.
  void OnProcessStarting(zx::exception exception_token,
                         zx_exception_info_t exception_info) override;

  // Computes the set of currently running processes that matches any of the |filters|.
  void ApplyToJob(FilterInfo& filter, JobHandle& job, ProcessHandleSetByKoid& matches);

  ProcessStartHandler* handler_;  // Non-owning.
  std::unique_ptr<JobHandle> job_handle_;

  // Handle for watching the process exceptions.
  debug_ipc::MessageLoop::WatchHandle job_watch_handle_;
  std::vector<FilterInfo> filters_;

  FXL_DISALLOW_COPY_AND_ASSIGN(DebuggedJob);
};

}  // namespace debug_agent

#endif  // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_JOB_H_
