// Copyright (c) 2012 The Chromium OS 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 DEBUGD_SRC_PACKET_CAPTURE_TOOL_H_
#define DEBUGD_SRC_PACKET_CAPTURE_TOOL_H_

#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>

#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_util.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>

#include "debugd/src/subprocess_tool.h"

namespace debugd {

class PacketCaptureTool : public SubprocessTool {
 public:
  PacketCaptureTool() = default;
  PacketCaptureTool(const PacketCaptureTool&) = delete;
  PacketCaptureTool& operator=(const PacketCaptureTool&) = delete;

  ~PacketCaptureTool() override = default;

  // Starts packet capture if the given options are valid. Runs
  // `on_packet_capture_stopped` when the started packet capture process is
  // stopped or terminated.
  bool Start(bool is_dev_mode,
             const base::ScopedFD& status_fd,
             const base::ScopedFD& output_fd,
             const brillo::VariantDictionary& options,
             std::string* out_id,
             base::OnceClosure on_packet_capture_stopped,
             brillo::ErrorPtr* error);

  // Returns false if there are no ongoing packet capture processes.
  bool HasActivePacketCaptureProcess();

 private:
  struct ChildProcessInfo {
    ChildProcessInfo(base::ScopedFD pipe_read_fd_in,
                     std::unique_ptr<base::FileDescriptorWatcher::Controller>
                         pipe_read_watcher_in,
                     base::OnceClosure on_stopped_callback_in)
        : pipe_read_fd(std::move(pipe_read_fd_in)),
          pipe_read_watcher(std::move(pipe_read_watcher_in)),
          on_stopped_callback(std::move(on_stopped_callback_in)) {}
    ~ChildProcessInfo() = default;

    // Move constructor.
    ChildProcessInfo(ChildProcessInfo&& info) {
      pipe_read_fd = std::move(info.pipe_read_fd);
      pipe_read_watcher = std::move(info.pipe_read_watcher);
      on_stopped_callback = std::move(info.on_stopped_callback);
    }

    // Delete the copy constructor.
    ChildProcessInfo(const ChildProcessInfo& child) = delete;

    // The pipe that'll be used to read the status update of the child process.
    base::ScopedFD pipe_read_fd;
    // FileDescriptorWatcher will watch the readable state of the pipe to detect
    // when the child process has ended.
    std::unique_ptr<base::FileDescriptorWatcher::Controller> pipe_read_watcher;
    // The callback that will be run the packet capture process terminates.
    base::OnceClosure on_stopped_callback;
  };

  debugd::ProcessWithId* CreateCaptureProcessForFrequencyBasedCapture(
      const brillo::VariantDictionary& options,
      int output_fd,
      brillo::ErrorPtr* error);
  debugd::ProcessWithId* CreateCaptureProcessForDeviceBasedCapture(
      const brillo::VariantDictionary& options,
      int output_fd,
      brillo::ErrorPtr* error);

  // Is called when a packet capture helper process has terminated. Checks the
  // ChildProcessInfo of the process with pid `process_handle` and runs
  // `on_packet_capture_stopped_callback`. Sets `hasPacketCaptureRunning_` to
  // false if there are no packet capture processes left running.
  void OnPacketCaptureStopped(std::string process_handle);

  // ProcessWithId::id() -> ChildProcessInfo.
  std::map<std::string, ChildProcessInfo> helper_processes_;
};

}  // namespace debugd

#endif  // DEBUGD_SRC_PACKET_CAPTURE_TOOL_H_
