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

#include "patchpanel/dbus/client.h"

#include <fcntl.h>

#include <algorithm>
#include <optional>
#include <ostream>

#include <base/functional/bind.h>
#include <base/logging.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/string_util.h>
#include <base/synchronization/waitable_event.h>
#include <base/task/bind_post_task.h>
#include <base/time/time.h>
#include <brillo/errors/error.h>
#include <brillo/http/http_transport.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/net-base/technology.h>
#include <dbus/message.h>
#include <dbus/object_path.h>
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
#include <patchpanel/proto_bindings/traffic_annotation.pb.h>

#include "patchpanel/dbus-proxies.h"

namespace patchpanel {

namespace {

using org::chromium::PatchPanelProxyInterface;

patchpanel::TrafficCounter::Source ConvertTrafficSource(
    Client::TrafficSource source) {
  switch (source) {
    case Client::TrafficSource::kUnknown:
      return patchpanel::TrafficCounter::UNKNOWN;
    case Client::TrafficSource::kChrome:
      return patchpanel::TrafficCounter::CHROME;
    case Client::TrafficSource::kUser:
      return patchpanel::TrafficCounter::USER;
    case Client::TrafficSource::kUpdateEngine:
      return patchpanel::TrafficCounter::UPDATE_ENGINE;
    case Client::TrafficSource::kSystem:
      return patchpanel::TrafficCounter::SYSTEM;
    case Client::TrafficSource::kVpn:
      return patchpanel::TrafficCounter::VPN;
    case Client::TrafficSource::kArc:
      return patchpanel::TrafficCounter::ARC;
    case Client::TrafficSource::kBorealisVM:
      return patchpanel::TrafficCounter::BOREALIS_VM;
    case Client::TrafficSource::kBruschettaVM:
      return patchpanel::TrafficCounter::BRUSCHETTA_VM;
    case Client::TrafficSource::kCrostiniVM:
      return patchpanel::TrafficCounter::CROSTINI_VM;
    case Client::TrafficSource::kParallelsVM:
      return patchpanel::TrafficCounter::PARALLELS_VM;
    case Client::TrafficSource::kTethering:
      return patchpanel::TrafficCounter::TETHERING;
    case Client::TrafficSource::kWiFiDirect:
      return patchpanel::TrafficCounter::WIFI_DIRECT;
    case Client::TrafficSource::kWiFiLOHS:
      return patchpanel::TrafficCounter::WIFI_LOHS;
  }
}

Client::TrafficSource ConvertTrafficSource(
    patchpanel::TrafficCounter::Source source) {
  switch (source) {
    case patchpanel::TrafficCounter::CHROME:
      return Client::TrafficSource::kChrome;
    case patchpanel::TrafficCounter::USER:
      return Client::TrafficSource::kUser;
    case patchpanel::TrafficCounter::UPDATE_ENGINE:
      return Client::TrafficSource::kUpdateEngine;
    case patchpanel::TrafficCounter::SYSTEM:
      return Client::TrafficSource::kSystem;
    case patchpanel::TrafficCounter::VPN:
      return Client::TrafficSource::kVpn;
    case patchpanel::TrafficCounter::ARC:
      return Client::TrafficSource::kArc;
    case patchpanel::TrafficCounter::BOREALIS_VM:
      return Client::TrafficSource::kBorealisVM;
    case patchpanel::TrafficCounter::BRUSCHETTA_VM:
      return Client::TrafficSource::kBruschettaVM;
    case patchpanel::TrafficCounter::CROSTINI_VM:
      return Client::TrafficSource::kCrostiniVM;
    case patchpanel::TrafficCounter::PARALLELS_VM:
      return Client::TrafficSource::kParallelsVM;
    case patchpanel::TrafficCounter::TETHERING:
      return Client::TrafficSource::kTethering;
    case patchpanel::TrafficCounter::WIFI_DIRECT:
      return Client::TrafficSource::kWiFiDirect;
    case patchpanel::TrafficCounter::WIFI_LOHS:
      return Client::TrafficSource::kWiFiLOHS;
    default:
      return Client::TrafficSource::kUnknown;
  }
}

patchpanel::NeighborReachabilityEventSignal::Role ConvertNeighborRole(
    Client::NeighborRole role) {
  switch (role) {
    case Client::NeighborRole::kGateway:
      return patchpanel::NeighborReachabilityEventSignal::GATEWAY;
    case Client::NeighborRole::kDnsServer:
      return patchpanel::NeighborReachabilityEventSignal::DNS_SERVER;
    case Client::NeighborRole::kGatewayAndDnsServer:
      return patchpanel::NeighborReachabilityEventSignal::
          GATEWAY_AND_DNS_SERVER;
  }
}

patchpanel::NeighborReachabilityEventSignal::EventType ConvertNeighborStatus(
    Client::NeighborStatus status) {
  switch (status) {
    case Client::NeighborStatus::kFailed:
      return patchpanel::NeighborReachabilityEventSignal::FAILED;
    case Client::NeighborStatus::kReachable:
      return patchpanel::NeighborReachabilityEventSignal::REACHABLE;
  }
}

patchpanel::ModifyPortRuleRequest::Operation ConvertFirewallRequestOperation(
    Client::FirewallRequestOperation op) {
  switch (op) {
    case Client::FirewallRequestOperation::kCreate:
      return ModifyPortRuleRequest::CREATE;
    case Client::FirewallRequestOperation::kDelete:
      return ModifyPortRuleRequest::DELETE;
  }
}

patchpanel::ModifyPortRuleRequest::RuleType ConvertFirewallRequestType(
    Client::FirewallRequestType type) {
  switch (type) {
    case Client::FirewallRequestType::kAccess:
      return ModifyPortRuleRequest::ACCESS;
    case Client::FirewallRequestType::kLockdown:
      return ModifyPortRuleRequest::LOCKDOWN;
    case Client::FirewallRequestType::kForwarding:
      return ModifyPortRuleRequest::FORWARDING;
  }
}

patchpanel::ModifyPortRuleRequest::Protocol ConvertFirewallRequestProtocol(
    Client::FirewallRequestProtocol protocol) {
  switch (protocol) {
    case Client::FirewallRequestProtocol::kTcp:
      return ModifyPortRuleRequest::TCP;
    case Client::FirewallRequestProtocol::kUdp:
      return ModifyPortRuleRequest::UDP;
  }
}

patchpanel::SetDnsRedirectionRuleRequest::RuleType
ConvertDnsRedirectionRequestType(Client::DnsRedirectionRequestType type) {
  switch (type) {
    case Client::DnsRedirectionRequestType::kDefault:
      return patchpanel::SetDnsRedirectionRuleRequest::DEFAULT;
    case Client::DnsRedirectionRequestType::kArc:
      return patchpanel::SetDnsRedirectionRuleRequest::ARC;
    case Client::DnsRedirectionRequestType::kUser:
      return patchpanel::SetDnsRedirectionRuleRequest::USER;
    case Client::DnsRedirectionRequestType::kExcludeDestination:
      return patchpanel::SetDnsRedirectionRuleRequest::EXCLUDE_DESTINATION;
  }
}

patchpanel::SetFeatureFlagRequest::FeatureFlag ConvertFeatureFlag(
    Client::FeatureFlag flag) {
  switch (flag) {
    case Client::FeatureFlag::kWiFiQoS:
      return patchpanel::SetFeatureFlagRequest::FeatureFlag::
          SetFeatureFlagRequest_FeatureFlag_WIFI_QOS;
    case Client::FeatureFlag::kClat:
      return patchpanel::SetFeatureFlagRequest::FeatureFlag::
          SetFeatureFlagRequest_FeatureFlag_CLAT;
  }
}

std::optional<net_base::IPv4CIDR> ConvertIPv4Subnet(const IPv4Subnet& in) {
  return net_base::IPv4CIDR::CreateFromBytesAndPrefix(
      in.addr(), static_cast<int>(in.prefix_len()));
}

std::optional<Client::TrafficCounter> ConvertTrafficCounter(
    const TrafficCounter& in) {
  auto out = std::make_optional<Client::TrafficCounter>();
  out->traffic.rx_bytes = in.rx_bytes();
  out->traffic.tx_bytes = in.tx_bytes();
  out->traffic.rx_packets = in.rx_packets();
  out->traffic.tx_packets = in.tx_packets();
  out->ifname = in.device();
  out->source = ConvertTrafficSource(in.source());
  switch (in.ip_family()) {
    case patchpanel::TrafficCounter::IPV4:
      out->ip_family = Client::IPFamily::kIPv4;
      break;
    case patchpanel::TrafficCounter::IPV6:
      out->ip_family = Client::IPFamily::kIPv6;
      break;
    default:
      LOG(ERROR) << __func__ << ": Unknown IpFamily "
                 << patchpanel::TrafficCounter::IpFamily_Name(in.ip_family());
      return std::nullopt;
  }
  return out;
}

std::optional<Client::VirtualDevice> ConvertVirtualDevice(
    const NetworkDevice& in) {
  auto out = std::make_optional<Client::VirtualDevice>();
  out->ifname = in.ifname();
  out->phys_ifname = in.phys_ifname();
  out->guest_ifname = in.guest_ifname();
  out->ipv4_addr = net_base::IPv4Address(in.ipv4_addr());
  out->host_ipv4_addr = net_base::IPv4Address(in.host_ipv4_addr());
  out->ipv4_subnet = ConvertIPv4Subnet(in.ipv4_subnet());

  out->dns_proxy_ipv4_addr =
      net_base::IPv4Address::CreateFromBytes(in.dns_proxy_ipv4_addr());
  out->dns_proxy_ipv6_addr =
      net_base::IPv6Address::CreateFromBytes(in.dns_proxy_ipv6_addr());
  switch (in.technology_type()) {
    case patchpanel::NetworkDevice::CELLULAR:
      out->technology = net_base::Technology::kCellular;
      break;
    case patchpanel::NetworkDevice::ETHERNET:
      out->technology = net_base::Technology::kEthernet;
      break;
    case patchpanel::NetworkDevice::WIFI:
      out->technology = net_base::Technology::kWiFi;
      break;
    default:
      out->technology = std::nullopt;
      break;
  }

  switch (in.guest_type()) {
    case patchpanel::NetworkDevice::ARC:
      out->guest_type = Client::GuestType::kArcContainer;
      break;
    case patchpanel::NetworkDevice::ARCVM:
      out->guest_type = Client::GuestType::kArcVm;
      break;
    case patchpanel::NetworkDevice::TERMINA_VM:
      out->guest_type = Client::GuestType::kTerminaVm;
      break;
    case patchpanel::NetworkDevice::PARALLELS_VM:
      out->guest_type = Client::GuestType::kParallelsVm;
      break;
    default:
      LOG(ERROR) << __func__ << ": Unknown GuestType "
                 << patchpanel::NetworkDevice::GuestType_Name(in.guest_type());
      return std::nullopt;
  }
  return out;
}

std::optional<Client::TerminaAllocation> ConvertTerminaAllocation(
    const TerminaVmStartupResponse& in) {
  if (!in.has_ipv4_subnet()) {
    LOG(ERROR) << __func__ << ": No Termina IPv4 subnet found";
    return std::nullopt;
  }
  if (!in.has_container_ipv4_subnet()) {
    LOG(ERROR) << __func__ << ": No Termina container IPv4 subnet found";
    return std::nullopt;
  }
  const auto termina_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  const auto termina_address =
      net_base::IPv4Address::CreateFromBytes(in.ipv4_address());
  const auto gateway_address =
      net_base::IPv4Address::CreateFromBytes(in.gateway_ipv4_address());
  const auto container_subnet = ConvertIPv4Subnet(in.container_ipv4_subnet());
  const auto container_address =
      net_base::IPv4Address::CreateFromBytes(in.container_ipv4_address());
  if (!termina_subnet) {
    LOG(ERROR) << __func__ << ": Invalid Termina IPv4 subnet";
    return std::nullopt;
  }
  if (!termina_address || !termina_subnet->InSameSubnetWith(*termina_address)) {
    LOG(ERROR) << __func__ << ": Invalid Termina IPv4 address";
    return std::nullopt;
  }
  if (!gateway_address || !termina_subnet->InSameSubnetWith(*gateway_address)) {
    LOG(ERROR) << __func__ << ": Invalid Termina gateway IPv4 address";
    return std::nullopt;
  }
  if (!container_subnet) {
    LOG(ERROR) << __func__ << ": Invalid Termina container IPv4 subnet";
    return std::nullopt;
  }
  if (!container_address) {
    LOG(ERROR) << __func__ << ": Invalid Termina container IPv4 address";
    return std::nullopt;
  }
  Client::TerminaAllocation termina_alloc;
  termina_alloc.tap_device_ifname = in.tap_device_ifname();
  termina_alloc.termina_ipv4_subnet = *termina_subnet;
  termina_alloc.termina_ipv4_address = *termina_address;
  termina_alloc.gateway_ipv4_address = *gateway_address;
  termina_alloc.container_ipv4_subnet = *container_subnet;
  termina_alloc.container_ipv4_address = *container_address;
  return termina_alloc;
}

std::optional<Client::ParallelsAllocation> ConvertParallelsAllocation(
    const ParallelsVmStartupResponse& in) {
  if (!in.has_ipv4_subnet()) {
    LOG(ERROR) << __func__ << ": No Parallels IPv4 subnet found";
    return std::nullopt;
  }
  const auto parallels_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  const auto parallels_address =
      net_base::IPv4Address::CreateFromBytes(in.ipv4_address());
  if (!parallels_subnet) {
    LOG(ERROR) << __func__ << ": Invalid Parallels IPv4 subnet";
    return std::nullopt;
  }
  if (!parallels_address ||
      !parallels_subnet->InSameSubnetWith(*parallels_address)) {
    LOG(ERROR) << __func__ << ": Invalid Parallels IPv4 address";
    return std::nullopt;
  }
  Client::ParallelsAllocation parallels_alloc;
  parallels_alloc.tap_device_ifname = in.tap_device_ifname();
  parallels_alloc.parallels_ipv4_subnet = *parallels_subnet;
  parallels_alloc.parallels_ipv4_address = *parallels_address;
  return parallels_alloc;
}

std::optional<Client::BruschettaAllocation> ConvertBruschettaAllocation(
    const BruschettaVmStartupResponse& in) {
  if (in.tap_device_ifname().empty()) {
    LOG(ERROR) << __func__ << ": No Bruschetta device interface found";
    return std::nullopt;
  }
  if (!in.has_ipv4_subnet()) {
    LOG(ERROR) << __func__ << ": No Bruschetta IPv4 subnet found";
    return std::nullopt;
  }
  const auto bruschetta_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  const auto bruschetta_address =
      net_base::IPv4Address::CreateFromBytes(in.ipv4_address());
  const auto gateway_address =
      net_base::IPv4Address::CreateFromBytes(in.gateway_ipv4_address());
  if (!bruschetta_subnet) {
    LOG(ERROR) << __func__ << ": Invalid Bruschetta IPv4 subnet";
    return std::nullopt;
  }
  if (!bruschetta_address ||
      !bruschetta_subnet->InSameSubnetWith(*bruschetta_address)) {
    LOG(ERROR) << __func__ << ": Invalid Bruschetta IPv4 address";
    return std::nullopt;
  }
  if (!gateway_address ||
      !bruschetta_subnet->InSameSubnetWith(*gateway_address)) {
    LOG(ERROR) << __func__ << ": Invalid Bruschetta gateway IPv4 address";
    return std::nullopt;
  }

  Client::BruschettaAllocation bruschetta_alloc;
  bruschetta_alloc.tap_device_ifname = in.tap_device_ifname();
  bruschetta_alloc.bruschetta_ipv4_subnet = *bruschetta_subnet;
  bruschetta_alloc.bruschetta_ipv4_address = *bruschetta_address;
  bruschetta_alloc.gateway_ipv4_address = *gateway_address;
  return bruschetta_alloc;
}

std::optional<Client::BorealisAllocation> ConvertBorealisAllocation(
    const BorealisVmStartupResponse& in) {
  if (in.tap_device_ifname().empty()) {
    LOG(ERROR) << __func__ << ": No Borealis device interface found";
    return std::nullopt;
  }
  if (!in.has_ipv4_subnet()) {
    LOG(ERROR) << __func__ << ": No Borealis IPv4 subnet found";
    return std::nullopt;
  }
  const auto borealis_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  const auto borealis_address =
      net_base::IPv4Address::CreateFromBytes(in.ipv4_address());
  const auto gateway_address =
      net_base::IPv4Address::CreateFromBytes(in.gateway_ipv4_address());
  if (!borealis_subnet) {
    LOG(ERROR) << __func__ << ": Invalid Borealis IPv4 subnet";
    return std::nullopt;
  }
  if (!borealis_address ||
      !borealis_subnet->InSameSubnetWith(*borealis_address)) {
    LOG(ERROR) << __func__ << ": Invalid Borealis IPv4 address";
    return std::nullopt;
  }
  if (!gateway_address ||
      !borealis_subnet->InSameSubnetWith(*gateway_address)) {
    LOG(ERROR) << __func__ << ": Invalid Borealis gateway IPv4 address";
    return std::nullopt;
  }

  Client::BorealisAllocation borealis_alloc;
  borealis_alloc.tap_device_ifname = in.tap_device_ifname();
  borealis_alloc.borealis_ipv4_subnet = *borealis_subnet;
  borealis_alloc.borealis_ipv4_address = *borealis_address;
  borealis_alloc.gateway_ipv4_address = *gateway_address;
  return borealis_alloc;
}

std::optional<Client::NetworkClientInfo> ConvertNetworkClientInfo(
    const NetworkClientInfo& in) {
  auto out = std::make_optional<Client::NetworkClientInfo>();
  std::copy(in.mac_addr().begin(), in.mac_addr().end(),
            std::back_inserter(out->mac_addr));
  const auto ipv4_addr = net_base::IPv4Address::CreateFromBytes(in.ipv4_addr());
  if (!ipv4_addr) {
    LOG(ERROR) << "Failed to convert protobuf bytes to IPv4Address. size="
               << in.ipv4_addr().size();
    return std::nullopt;
  }
  out->ipv4_addr = *ipv4_addr;
  for (const auto& in_ipv6_addr : in.ipv6_addresses()) {
    const auto ipv6_addr = net_base::IPv6Address::CreateFromBytes(in_ipv6_addr);
    if (!ipv6_addr) {
      LOG(ERROR) << "Failed to convert protobuf bytes to IPv6Address. size="
                 << in_ipv6_addr.size();
      return std::nullopt;
    }
    out->ipv6_addresses.push_back(*ipv6_addr);
  }
  out->hostname = in.hostname();
  out->vendor_class = in.vendor_class();
  return out;
}

std::optional<Client::DownstreamNetwork> ConvertDownstreamNetwork(
    const DownstreamNetwork& in) {
  auto out = std::make_optional<Client::DownstreamNetwork>();
  out->network_id = in.network_id();
  out->ifname = in.downstream_ifname();

  const auto ipv4_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  if (!ipv4_subnet) {
    LOG(ERROR) << "Failed to create IPv4CIDR for ipv4_subnet";
    return std::nullopt;
  }
  out->ipv4_subnet = *ipv4_subnet;

  const auto ipv4_gateway_addr =
      net_base::IPv4Address::CreateFromBytes(in.ipv4_gateway_addr());
  if (!ipv4_gateway_addr) {
    LOG(ERROR) << "Failed to create IPv4Address for gateway address: size="
               << in.ipv4_gateway_addr().size();
    return std::nullopt;
  }
  out->ipv4_gateway_addr = *ipv4_gateway_addr;
  return out;
}

patchpanel::NetworkTechnology ConvertNetworkTechnology(
    Client::NetworkTechnology network_technology) {
  switch (network_technology) {
    case Client::NetworkTechnology::kCellular:
      return patchpanel::NetworkTechnology::CELLULAR;
    case Client::NetworkTechnology::kEthernet:
      return patchpanel::NetworkTechnology::ETHERNET;
    case Client::NetworkTechnology::kVPN:
      return patchpanel::NetworkTechnology::VPN;
    case Client::NetworkTechnology::kWiFi:
      return patchpanel::NetworkTechnology::WIFI;
  }
}

TagSocketRequest::VpnRoutingPolicy ConvertVpnRoutingPolicy(
    Client::VpnRoutingPolicy policy) {
  switch (policy) {
    case Client::VpnRoutingPolicy::kDefaultRouting:
      return TagSocketRequest::DEFAULT_ROUTING;
    case Client::VpnRoutingPolicy::kBypassVpn:
      return TagSocketRequest::BYPASS_VPN;
    case Client::VpnRoutingPolicy::kRouteOnVpn:
      return TagSocketRequest::ROUTE_ON_VPN;
  }
}

traffic_annotation::TrafficAnnotation::Id ConvertTrafficAnnotationId(
    Client::TrafficAnnotationId id) {
  switch (id) {
    case Client::TrafficAnnotationId::kUnspecified:
      return traffic_annotation::TrafficAnnotation::UNSPECIFIED;
    case Client::TrafficAnnotationId::kShillPortalDetector:
      return traffic_annotation::TrafficAnnotation::SHILL_PORTAL_DETECTOR;
    case Client::TrafficAnnotationId::kShillCapportClient:
      return traffic_annotation::TrafficAnnotation::SHILL_CAPPORT_CLIENT;
    case Client::TrafficAnnotationId::kShillCarrierEntitlement:
      return traffic_annotation::TrafficAnnotation::SHILL_CARRIER_ENTITLEMENT;
  }
}

std::optional<Client::NeighborReachabilityEvent>
ConvertNeighborReachabilityEvent(const NeighborReachabilityEventSignal& in) {
  auto out = std::make_optional<Client::NeighborReachabilityEvent>();
  out->ifindex = in.ifindex();
  out->ip_addr = in.ip_addr();
  switch (in.role()) {
    case patchpanel::NeighborReachabilityEventSignal::GATEWAY:
      out->role = Client::NeighborRole::kGateway;
      break;
    case patchpanel::NeighborReachabilityEventSignal::DNS_SERVER:
      out->role = Client::NeighborRole::kDnsServer;
      break;
    case patchpanel::NeighborReachabilityEventSignal::GATEWAY_AND_DNS_SERVER:
      out->role = Client::NeighborRole::kGatewayAndDnsServer;
      break;
    default:
      LOG(ERROR) << __func__ << ": Unknown NeighborReachability role "
                 << patchpanel::NeighborReachabilityEventSignal::Role_Name(
                        in.role());
      return std::nullopt;
  }
  switch (in.type()) {
    case patchpanel::NeighborReachabilityEventSignal::FAILED:
      out->status = Client::NeighborStatus::kFailed;
      break;
    case patchpanel::NeighborReachabilityEventSignal::REACHABLE:
      out->status = Client::NeighborStatus::kReachable;
      break;
    default:
      LOG(ERROR) << __func__ << ": Unknown NeighborReachability event type "
                 << patchpanel::NeighborReachabilityEventSignal::EventType_Name(
                        in.type());
      return std::nullopt;
  }
  return out;
}

std::optional<Client::VirtualDeviceEvent> ConvertVirtualDeviceEvent(
    const NetworkDeviceChangedSignal& in) {
  switch (in.event()) {
    case patchpanel::NetworkDeviceChangedSignal::DEVICE_ADDED:
      return Client::VirtualDeviceEvent::kAdded;
    case patchpanel::NetworkDeviceChangedSignal::DEVICE_REMOVED:
      return Client::VirtualDeviceEvent::kRemoved;
    default:
      LOG(ERROR) << __func__ << ": Unknown NetworkDeviceChangedSignal event "
                 << patchpanel::NetworkDeviceChangedSignal::Event_Name(
                        in.event());
      return std::nullopt;
  }
}

std::optional<Client::ConnectedNamespace> ConvertConnectedNamespace(
    const ConnectNamespaceResponse& in) {
  auto out = std::make_optional<Client::ConnectedNamespace>();

  const auto ipv4_subnet = ConvertIPv4Subnet(in.ipv4_subnet());
  if (!ipv4_subnet) {
    LOG(ERROR) << "Failed to create IPv4CIDR for ipv4_subnet";
    return std::nullopt;
  }
  out->ipv4_subnet = *ipv4_subnet;

  out->peer_ifname = in.peer_ifname();
  out->peer_ipv4_address = net_base::IPv4Address(in.peer_ipv4_address());
  out->host_ifname = in.host_ifname();
  out->host_ipv4_address = net_base::IPv4Address(in.host_ipv4_address());
  out->netns_name = in.netns_name();
  return out;
}

std::ostream& operator<<(std::ostream& stream,
                         const ModifyPortRuleRequest& request) {
  stream << "{ operation: "
         << ModifyPortRuleRequest::Operation_Name(request.op())
         << ", rule type: "
         << ModifyPortRuleRequest::RuleType_Name(request.type())
         << ", protocol: "
         << ModifyPortRuleRequest::Protocol_Name(request.proto());
  if (!request.input_ifname().empty()) {
    stream << ", input interface name: " << request.input_ifname();
  }
  if (!request.input_dst_ip().empty()) {
    stream << ", input destination IP: " << request.input_dst_ip();
  }
  stream << ", input destination port: " << request.input_dst_port();
  if (!request.dst_ip().empty()) {
    stream << ", destination IP: " << request.dst_ip();
  }
  if (request.dst_port() != 0) {
    stream << ", destination port: " << request.dst_port();
  }
  stream << " }";
  return stream;
}

std::ostream& operator<<(std::ostream& stream,
                         const SetDnsRedirectionRuleRequest& request) {
  stream << "{ proxy type: "
         << SetDnsRedirectionRuleRequest::RuleType_Name(request.type());
  if (!request.input_ifname().empty()) {
    stream << ", input interface name: " << request.input_ifname();
  }
  if (!request.proxy_address().empty()) {
    stream << ", proxy IPv4 address: " << request.proxy_address();
  }
  if (!request.nameservers().empty()) {
    std::vector<std::string> nameservers;
    for (const auto& ns : request.nameservers()) {
      nameservers.emplace_back(ns);
    }
    stream << ", nameserver(s): " << base::JoinString(nameservers, ",");
  }
  stream << " }";
  return stream;
}

std::ostream& operator<<(std::ostream& stream, const Client::FeatureFlag flag) {
  switch (flag) {
    case Client::FeatureFlag::kWiFiQoS:
      return stream << "WiFiQoS";
    case Client::FeatureFlag::kClat:
      return stream << "Clat";
  }
}

// Prepares a pair of ScopedFDs corresponding to the write end (pair first
// element) and read end (pair second element) of a Linux pipe. The client must
// keep the write end alive until the setup requested from patchpanel is not
// necessary anymore.
std::pair<base::ScopedFD, base::ScopedFD> CreateLifelineFd() {
  int pipe_fds[2] = {-1, -1};
  if (pipe2(pipe_fds, O_CLOEXEC) < 0) {
    PLOG(ERROR) << "Failed to create a pair of fds with pipe2()";
    return {};
  }
  return {base::ScopedFD(pipe_fds[0]), base::ScopedFD(pipe_fds[1])};
}

void OnGetTrafficCountersDBusResponse(
    Client::GetTrafficCountersCallback callback,
    const TrafficCountersResponse& response) {
  std::vector<Client::TrafficCounter> counters;
  for (const auto& proto_counter : response.counters()) {
    auto client_counter = ConvertTrafficCounter(proto_counter);
    if (client_counter) {
      counters.push_back(*client_counter);
    }
  }
  std::move(callback).Run(counters);
}

void OnGetTrafficCountersError(Client::GetTrafficCountersCallback callback,
                               brillo::Error* error) {
  LOG(ERROR) << __func__ << "(): " << error->GetMessage();
  std::move(callback).Run({});
}

void OnNetworkDeviceChanged(
    Client::VirtualDeviceEventHandler handler,
    const patchpanel::NetworkDeviceChangedSignal& signal) {
  const auto event = ConvertVirtualDeviceEvent(signal);
  if (!event) {
    return;
  }

  const auto device = ConvertVirtualDevice(signal.device());
  if (!device) {
    return;
  }

  handler.Run(*event, *device);
}

void OnNeighborReachabilityEvent(
    const Client::NeighborReachabilityEventHandler& handler,
    const NeighborReachabilityEventSignal& signal) {
  const auto event = ConvertNeighborReachabilityEvent(signal);
  if (event) {
    handler.Run(*event);
  }
}

void OnSignalConnectedCallback(const std::string& interface_name,
                               const std::string& signal_name,
                               bool success) {
  if (!success)
    LOG(ERROR) << "Failed to connect to " << signal_name;
}

// Helper static function to process answers to CreateTetheredNetwork calls.
void OnTetheredNetworkResponse(Client::CreateTetheredNetworkCallback callback,
                               base::ScopedFD fd_local,
                               const TetheredNetworkResponse& response) {
  if (response.response_code() != DownstreamNetworkResult::SUCCESS) {
    LOG(ERROR) << kCreateTetheredNetworkMethod << " failed: "
               << patchpanel::DownstreamNetworkResult_Name(
                      response.response_code());
    std::move(callback).Run({}, {});
    return;
  }

  std::optional<Client::DownstreamNetwork> downstream_network =
      ConvertDownstreamNetwork(response.downstream_network());
  if (!downstream_network) {
    std::move(callback).Run({}, {});
    return;
  }

  std::move(callback).Run(std::move(fd_local), *downstream_network);
}

void OnTetheredNetworkError(Client::CreateTetheredNetworkCallback callback,
                            brillo::Error* error) {
  LOG(ERROR) << __func__ << "(): " << error->GetMessage();
  std::move(callback).Run({}, {});
}

// Helper static function to process answers to CreateLocalOnlyNetwork calls.
void OnLocalOnlyNetworkResponse(Client::CreateLocalOnlyNetworkCallback callback,
                                base::ScopedFD fd_local,
                                const LocalOnlyNetworkResponse& response) {
  if (response.response_code() != DownstreamNetworkResult::SUCCESS) {
    LOG(ERROR) << kCreateLocalOnlyNetworkMethod << " failed: "
               << patchpanel::DownstreamNetworkResult_Name(
                      response.response_code());
    std::move(callback).Run({}, {});
    return;
  }

  std::optional<Client::DownstreamNetwork> downstream_network =
      ConvertDownstreamNetwork(response.downstream_network());
  if (!downstream_network) {
    std::move(callback).Run({}, {});
    return;
  }

  std::move(callback).Run(std::move(fd_local), *downstream_network);
}

void OnLocalOnlyNetworkError(Client::CreateLocalOnlyNetworkCallback callback,
                             brillo::Error* error) {
  LOG(ERROR) << __func__ << "(): " << error->GetMessage();
  std::move(callback).Run({}, {});
}

// Helper static function to process answers to GetDownstreamNetworkInfo calls.
void OnGetDownstreamNetworkInfoResponse(
    Client::GetDownstreamNetworkInfoCallback callback,
    const GetDownstreamNetworkInfoResponse& response) {
  std::optional<Client::DownstreamNetwork> downstream_network =
      ConvertDownstreamNetwork(response.downstream_network());
  if (!downstream_network) {
    std::move(callback).Run(false, {}, {});
    return;
  }

  std::vector<Client::NetworkClientInfo> clients_info;
  for (const auto& ci : response.clients_info()) {
    const auto info = ConvertNetworkClientInfo(ci);
    if (info) {
      clients_info.push_back(*info);
    }
  }

  std::move(callback).Run(true, *downstream_network, clients_info);
}

void OnGetDownstreamNetworkInfoError(
    Client::GetDownstreamNetworkInfoCallback callback, brillo::Error* error) {
  LOG(ERROR) << __func__ << "(): " << error->GetMessage();
  std::move(callback).Run(false, {}, {});
}

void OnConfigureNetworkResponse(
    Client::ConfigureNetworkCallback callback,
    const std::string& ifname,
    const patchpanel::ConfigureNetworkResponse& response) {
  if (!response.success()) {
    LOG(ERROR) << __func__ << ": Failed to configure Network on " << ifname;
    std::move(callback).Run(false);
    return;
  }
  std::move(callback).Run(true);
}

void OnConfigureNetworkError(Client::ConfigureNetworkCallback callback,
                             const std::string& ifname,
                             brillo::Error* error) {
  LOG(ERROR) << __func__ << "() on " << ifname << ": " << error->GetMessage();
  std::move(callback).Run(false);
}

void OnTagSocketResponse(Client::TagSocketCallback callback,
                         const patchpanel::TagSocketResponse& response) {
  if (!response.success()) {
    LOG(ERROR) << __func__ << "(): failed to tag socket";
    std::move(callback).Run(false);
    return;
  }
  std::move(callback).Run(true);
}

void OnTagSocketError(Client::TagSocketCallback callback,
                      brillo::Error* error) {
  LOG(ERROR) << __func__ << "(): " << error->GetMessage();
  std::move(callback).Run(false);
}

class ClientImpl : public Client {
 public:
  ClientImpl(scoped_refptr<dbus::Bus> bus,
             std::unique_ptr<org::chromium::PatchPanelProxyInterface> proxy,
             bool owns_bus)
      : bus_(std::move(bus)), proxy_(std::move(proxy)), owns_bus_(owns_bus) {}

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

  ~ClientImpl() override;

  void RegisterOnAvailableCallback(
      base::OnceCallback<void(bool)> callback) override;

  void RegisterProcessChangedCallback(
      base::RepeatingCallback<void(bool)> callback) override;

  bool NotifyArcStartup(pid_t pid) override;
  bool NotifyArcShutdown() override;

  std::optional<Client::ArcVMAllocation> NotifyArcVmStartup(
      uint32_t cid) override;
  bool NotifyArcVmShutdown(uint32_t cid) override;

  std::optional<Client::TerminaAllocation> NotifyTerminaVmStartup(
      uint32_t cid) override;
  bool NotifyTerminaVmShutdown(uint32_t cid) override;

  std::optional<ParallelsAllocation> NotifyParallelsVmStartup(
      uint64_t vm_id, int subnet_index) override;
  bool NotifyParallelsVmShutdown(uint64_t vm_id) override;

  std::optional<BruschettaAllocation> NotifyBruschettaVmStartup(
      uint64_t vm_id) override;
  bool NotifyBruschettaVmShutdown(uint64_t vm_id) override;

  std::optional<BorealisAllocation> NotifyBorealisVmStartup(
      uint32_t vm_id) override;
  bool NotifyBorealisVmShutdown(uint32_t vm_id) override;

  std::pair<base::ScopedFD, Client::ConnectedNamespace> ConnectNamespace(
      pid_t pid,
      const std::string& outbound_ifname,
      bool forward_user_traffic,
      bool route_on_vpn,
      Client::TrafficSource traffic_source,
      bool static_ipv6) override;

  void GetTrafficCounters(const std::set<std::string>& devices,
                          GetTrafficCountersCallback callback) override;

  bool ModifyPortRule(Client::FirewallRequestOperation op,
                      Client::FirewallRequestType type,
                      Client::FirewallRequestProtocol proto,
                      const std::string& input_ifname,
                      const std::string& input_dst_ip,
                      uint32_t input_dst_port,
                      const std::string& dst_ip,
                      uint32_t dst_port) override;

  void SetVpnLockdown(bool enable) override;

  base::ScopedFD RedirectDns(Client::DnsRedirectionRequestType type,
                             const std::string& input_ifname,
                             const std::string& proxy_address,
                             const std::vector<std::string>& nameservers,
                             const std::string& host_ifname) override;

  std::vector<Client::VirtualDevice> GetDevices() override;

  void RegisterVirtualDeviceEventHandler(
      VirtualDeviceEventHandler handler) override;

  void RegisterNeighborReachabilityEventHandler(
      NeighborReachabilityEventHandler handler) override;

  bool CreateTetheredNetwork(
      const std::string& downstream_ifname,
      const std::string& upstream_ifname,
      const std::optional<DHCPOptions>& dhcp_options,
      const std::optional<UplinkIPv6Configuration>& uplink_ipv6_config,
      const std::optional<int>& mtu,
      CreateTetheredNetworkCallback callback) override;

  bool CreateLocalOnlyNetwork(const std::string& ifname,
                              CreateLocalOnlyNetworkCallback callback) override;

  bool GetDownstreamNetworkInfo(
      const std::string& ifname,
      GetDownstreamNetworkInfoCallback callback) override;

  bool ConfigureNetwork(int interface_index,
                        std::string_view interface_name,
                        uint32_t area,
                        const net_base::NetworkConfig& network_config,
                        net_base::NetworkPriority priority,
                        NetworkTechnology technology,
                        ConfigureNetworkCallback callback) override;

  bool SendSetFeatureFlagRequest(FeatureFlag flag, bool enable) override;

  bool TagSocket(base::ScopedFD fd,
                 std::optional<int> network_id,
                 std::optional<VpnRoutingPolicy> vpn_policy,
                 std::optional<TrafficAnnotation> traffic_annotation,
                 TagSocketCallback callback) override;

  void PrepareTagSocket(
      const TrafficAnnotation& annotation,
      std::shared_ptr<brillo::http::Transport> transport) override;

 private:
  // Runs the |task| on the DBus thread synchronously.
  // The generated proxy uses brillo::dbus_utils::CallMethod*(), which asserts
  // to be executed on the DBus thread, instead of hopping on the DBus thread.
  // Therefore we need to do it by ourselves.
  bool RunOnDBusThreadSync(base::OnceCallback<bool()> task) {
    if (!bus_->HasDBusThread() ||
        bus_->GetDBusTaskRunner()->RunsTasksInCurrentSequence()) {
      return std::move(task).Run();
    }

    base::WaitableEvent event;
    bool result = false;
    bus_->GetDBusTaskRunner()->PostTask(
        FROM_HERE, base::BindOnce(
                       [](base::OnceCallback<bool()> task, bool* result,
                          base::WaitableEvent* event) {
                         *result = std::move(task).Run();
                         event->Signal();
                       },
                       std::move(task), base::Unretained(&result),
                       base::Unretained(&event)));
    event.Wait();
    return result;
  }

  // Runs the |task| on the DBus thread asynchronously.
  // The generated proxy uses brillo::dbus_utils::CallMethod*(), which asserts
  // to be executed on the DBus thread, instead of hopping on the DBus thread.
  // Therefore we need to do it by ourselves.
  void RunOnDBusThreadAsync(base::OnceClosure task) {
    if (!bus_->HasDBusThread() ||
        bus_->GetDBusTaskRunner()->RunsTasksInCurrentSequence()) {
      std::move(task).Run();
      return;
    }

    bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, std::move(task));
  }

  scoped_refptr<dbus::Bus> bus_;
  std::unique_ptr<org::chromium::PatchPanelProxyInterface> proxy_;
  bool owns_bus_;  // Yes if |bus_| is created by Client::New

  base::RepeatingCallback<void(bool)> owner_callback_;

  void OnOwnerChanged(const std::string& old_owner,
                      const std::string& new_owner);

  base::WeakPtrFactory<ClientImpl> weak_factory_{this};
};

ClientImpl::~ClientImpl() {
  if (bus_ && owns_bus_)
    bus_->ShutdownAndBlock();
}

void ClientImpl::RegisterOnAvailableCallback(
    base::OnceCallback<void(bool)> callback) {
  auto* object_proxy = proxy_->GetObjectProxy();
  if (!object_proxy) {
    LOG(ERROR) << "Cannot register callback - no proxy";
    return;
  }
  object_proxy->WaitForServiceToBeAvailable(std::move(callback));
}

void ClientImpl::RegisterProcessChangedCallback(
    base::RepeatingCallback<void(bool)> callback) {
  owner_callback_ = callback;
  bus_->GetObjectProxy(kPatchPanelServiceName, dbus::ObjectPath{"/"})
      ->SetNameOwnerChangedCallback(base::BindRepeating(
          &ClientImpl::OnOwnerChanged, weak_factory_.GetWeakPtr()));
}

void ClientImpl::OnOwnerChanged(const std::string& old_owner,
                                const std::string& new_owner) {
  if (new_owner.empty()) {
    LOG(INFO) << "Patchpanel lost";
    if (!owner_callback_.is_null())
      owner_callback_.Run(false);
    return;
  }

  LOG(INFO) << "Patchpanel reset";
  if (!owner_callback_.is_null())
    owner_callback_.Run(true);
}

bool ClientImpl::NotifyArcStartup(pid_t pid) {
  ArcStartupRequest request;
  request.set_pid(pid);

  // TODO(b/284076578): Check if we can call the DBus method asynchronously.
  ArcStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const ArcStartupRequest& request,
         ArcStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->ArcStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "ARC network startup failed: " << error->GetMessage();
    return false;
  }

  return true;
}

bool ClientImpl::NotifyArcShutdown() {
  // TODO(b/284076578): Check if we can call the DBus method asynchronously.
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, brillo::ErrorPtr* error) {
        ArcShutdownResponse response;
        return proxy->ArcShutdown({}, &response, error);
      },
      proxy_.get(), &error));
  if (!result) {
    LOG(ERROR) << "ARC network shutdown failed: " << error->GetMessage();
    return false;
  }

  return true;
}

std::optional<Client::ArcVMAllocation> ClientImpl::NotifyArcVmStartup(
    uint32_t cid) {
  ArcVmStartupRequest request;
  request.set_cid(cid);

  // TODO(b/284076578): Check if concierge can handle the result asynchronously.
  ArcVmStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const ArcVmStartupRequest& request,
         ArcVmStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->ArcVmStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "ARCVM network startup failed: " << error->GetMessage();
    return std::nullopt;
  }

  const auto arc0_addr =
      net_base::IPv4Address::CreateFromBytes(response.arc0_ipv4_address());
  if (!arc0_addr) {
    LOG(ERROR) << "Could not deserialize arc0 IPv4 address";
    return std::nullopt;
  }

  ArcVMAllocation arcvm_alloc;
  arcvm_alloc.arc0_ipv4_address = *arc0_addr;
  for (const auto& tap : response.tap_device_ifnames()) {
    arcvm_alloc.tap_device_ifnames.push_back(tap);
  }
  return arcvm_alloc;
}

bool ClientImpl::NotifyArcVmShutdown(uint32_t cid) {
  ArcVmShutdownRequest request;
  request.set_cid(cid);

  // TODO(b/284076578): Check if concierge can handle the result asynchronously.
  ArcVmShutdownResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const ArcVmShutdownRequest& request,
         ArcVmShutdownResponse* response, brillo::ErrorPtr* error) {
        return proxy->ArcVmShutdown(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "ARCVM network shutdown failed: " << error->GetMessage();
  }

  return result;
}

std::optional<Client::TerminaAllocation> ClientImpl::NotifyTerminaVmStartup(
    uint32_t cid) {
  TerminaVmStartupRequest request;
  request.set_cid(cid);

  TerminaVmStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const TerminaVmStartupRequest& request,
         TerminaVmStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->TerminaVmStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));

  if (!result) {
    LOG(ERROR) << __func__ << "(cid: " << cid
               << "): TerminaVM network startup failed: "
               << error->GetMessage();
    return std::nullopt;
  }

  const auto termina_alloc = ConvertTerminaAllocation(response);
  if (!termina_alloc) {
    LOG(ERROR) << __func__ << "(cid: " << cid
               << "): Failed to convert network allocation";
  }
  return termina_alloc;
}

bool ClientImpl::NotifyTerminaVmShutdown(uint32_t cid) {
  TerminaVmShutdownRequest request;
  request.set_cid(cid);

  TerminaVmShutdownResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const TerminaVmShutdownRequest& request,
         TerminaVmShutdownResponse* response, brillo::ErrorPtr* error) {
        return proxy->TerminaVmShutdown(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "TerminaVM network shutdown failed: " << error->GetMessage();
    return false;
  }
  return true;
}

std::optional<Client::ParallelsAllocation> ClientImpl::NotifyParallelsVmStartup(
    uint64_t vm_id, int subnet_index) {
  ParallelsVmStartupRequest request;
  request.set_id(vm_id);
  request.set_subnet_index(subnet_index);

  ParallelsVmStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const ParallelsVmStartupRequest& request,
         ParallelsVmStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->ParallelsVmStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));

  if (!result) {
    LOG(ERROR) << __func__ << "(cid: " << vm_id
               << ", subnet_index: " << subnet_index
               << "): Parallels VM network startup failed: "
               << error->GetMessage();
    return std::nullopt;
  }

  const auto network_alloc = ConvertParallelsAllocation(response);
  if (!network_alloc) {
    LOG(ERROR) << __func__ << "(cid: " << vm_id
               << ", subnet_index: " << subnet_index
               << "): Failed to convert Parallels VM network configuration";
  }
  return network_alloc;
}

bool ClientImpl::NotifyParallelsVmShutdown(uint64_t vm_id) {
  ParallelsVmShutdownRequest request;
  request.set_id(vm_id);

  ParallelsVmShutdownResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const ParallelsVmShutdownRequest& request,
         ParallelsVmShutdownResponse* response, brillo::ErrorPtr* error) {
        return proxy->ParallelsVmShutdown(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "ParallelsVM network shutdown failed: "
               << error->GetMessage();
    return false;
  }
  return true;
}

std::optional<Client::BruschettaAllocation>
ClientImpl::NotifyBruschettaVmStartup(uint64_t vm_id) {
  BruschettaVmStartupRequest request;
  request.set_id(vm_id);

  BruschettaVmStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const BruschettaVmStartupRequest& request,
         BruschettaVmStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->BruschettaVmStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));

  if (!result) {
    LOG(ERROR) << __func__ << "(vm_id: " << vm_id
               << "): Bruschetta VM network startup failed: "
               << error->GetMessage();
    return std::nullopt;
  }

  const auto network_alloc = ConvertBruschettaAllocation(response);
  if (!network_alloc) {
    LOG(ERROR) << __func__ << "(vm_id: " << vm_id
               << "): Failed to convert Bruschetta VM network configuration";
  }
  return network_alloc;
}

bool ClientImpl::NotifyBruschettaVmShutdown(uint64_t vm_id) {
  BruschettaVmShutdownRequest request;
  request.set_id(vm_id);

  BruschettaVmShutdownResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const BruschettaVmShutdownRequest& request,
         BruschettaVmShutdownResponse* response, brillo::ErrorPtr* error) {
        return proxy->BruschettaVmShutdown(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "BruschettaVM network shutdown failed: "
               << error->GetMessage();
    return false;
  }
  return true;
}

std::optional<Client::BorealisAllocation> ClientImpl::NotifyBorealisVmStartup(
    uint32_t vm_id) {
  BorealisVmStartupRequest request;
  request.set_id(vm_id);

  BorealisVmStartupResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const BorealisVmStartupRequest& request,
         BorealisVmStartupResponse* response, brillo::ErrorPtr* error) {
        return proxy->BorealisVmStartup(request, response, error);
      },
      proxy_.get(), request, &response, &error));

  if (!result) {
    LOG(ERROR) << __func__ << "(vm_id: " << vm_id
               << "): Borealis VM network startup failed: "
               << error->GetMessage();
    return std::nullopt;
  }

  const auto network_alloc = ConvertBorealisAllocation(response);
  if (!network_alloc) {
    LOG(ERROR) << __func__ << "(vm_id: " << vm_id
               << "): Failed to convert Borealis VM network configuration";
  }
  return network_alloc;
}

bool ClientImpl::NotifyBorealisVmShutdown(uint32_t vm_id) {
  BorealisVmShutdownRequest request;
  request.set_id(vm_id);

  BorealisVmShutdownResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const BorealisVmShutdownRequest& request,
         BorealisVmShutdownResponse* response, brillo::ErrorPtr* error) {
        return proxy->BorealisVmShutdown(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "Borealis VM network shutdown failed: "
               << error->GetMessage();
    return false;
  }
  return true;
}

std::pair<base::ScopedFD, Client::ConnectedNamespace>
ClientImpl::ConnectNamespace(pid_t pid,
                             const std::string& outbound_ifname,
                             bool forward_user_traffic,
                             bool route_on_vpn,
                             Client::TrafficSource traffic_source,
                             bool static_ipv6) {
  // Prepare and serialize the request proto.
  ConnectNamespaceRequest request;
  request.set_pid(static_cast<int32_t>(pid));
  request.set_outbound_physical_device(outbound_ifname);
  request.set_allow_user_traffic(forward_user_traffic);
  request.set_route_on_vpn(route_on_vpn);
  request.set_traffic_source(ConvertTrafficSource(traffic_source));
  request.set_static_ipv6(static_ipv6);

  auto [fd_local, fd_remote] = CreateLifelineFd();
  if (!fd_local.is_valid()) {
    LOG(ERROR)
        << "Cannot send ConnectNamespace message to patchpanel: no lifeline fd";
    return {};
  }

  ConnectNamespaceResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const ConnectNamespaceRequest& request, base::ScopedFD fd_remote,
         ConnectNamespaceResponse* response, brillo::ErrorPtr* error) {
        return proxy->ConnectNamespace(request, fd_remote, response, error);
      },
      proxy_.get(), request, std::move(fd_remote), &response, &error));
  if (!result) {
    LOG(ERROR) << "ConnectNamespace failed: " << error->GetMessage();
    return {};
  }

  if (response.peer_ifname().empty() || response.host_ifname().empty()) {
    LOG(ERROR) << "ConnectNamespace for netns pid " << pid << " failed";
    return {};
  }

  const auto connected_ns = ConvertConnectedNamespace(response);
  if (!connected_ns) {
    LOG(ERROR) << "Failed to convert ConnectedNamespace";
    return {};
  }

  LOG(INFO) << "ConnectNamespace for netns pid " << pid
            << " succeeded: peer_ifname=" << connected_ns->peer_ifname
            << " peer_ipv4_address=" << connected_ns->peer_ipv4_address
            << " host_ifname=" << connected_ns->host_ifname
            << " host_ipv4_address=" << connected_ns->host_ipv4_address
            << " subnet=" << connected_ns->ipv4_subnet.ToString();

  return std::make_pair(std::move(fd_local), *connected_ns);
}

void ClientImpl::GetTrafficCounters(const std::set<std::string>& devices,
                                    GetTrafficCountersCallback callback) {
  TrafficCountersRequest request;
  for (const auto& device : devices) {
    request.add_devices(device);
  }

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const TrafficCountersRequest& request,
         GetTrafficCountersCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->GetTrafficCountersAsync(
            request,
            base::BindOnce(&OnGetTrafficCountersDBusResponse,
                           std::move(split_callback.first)),
            base::BindOnce(&OnGetTrafficCountersError,
                           std::move(split_callback.second)));
      },
      proxy_.get(), request,
      base::BindPostTaskToCurrentDefault(std::move(callback))));
}

bool ClientImpl::ModifyPortRule(Client::FirewallRequestOperation op,
                                Client::FirewallRequestType type,
                                Client::FirewallRequestProtocol proto,
                                const std::string& input_ifname,
                                const std::string& input_dst_ip,
                                uint32_t input_dst_port,
                                const std::string& dst_ip,
                                uint32_t dst_port) {
  ModifyPortRuleRequest request;
  request.set_op(ConvertFirewallRequestOperation(op));
  request.set_type(ConvertFirewallRequestType(type));
  request.set_proto(ConvertFirewallRequestProtocol(proto));
  request.set_input_ifname(input_ifname);
  request.set_input_dst_ip(input_dst_ip);
  request.set_input_dst_port(input_dst_port);
  request.set_dst_ip(dst_ip);
  request.set_dst_port(dst_port);

  // TODO(b/284797476): Switch permission_brokker to use the async DBus call.
  ModifyPortRuleResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const ModifyPortRuleRequest& request,
         ModifyPortRuleResponse* response, brillo::ErrorPtr* error) {
        return proxy->ModifyPortRule(request, response, error);
      },
      proxy_.get(), request, &response, &error));
  if (!result) {
    LOG(ERROR) << "ModifyPortRule failed: " << error->GetMessage();
    return false;
  }

  if (!response.success()) {
    LOG(ERROR) << "ModifyPortRuleRequest failed " << request;
    return false;
  }
  return true;
}

void ClientImpl::SetVpnLockdown(bool enable) {
  SetVpnLockdownRequest request;
  request.set_enable_vpn_lockdown(enable);

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const SetVpnLockdownRequest& request) {
        // This API doesn't return anything.
        auto success_callback = base::DoNothing();
        // The current use case do not care about failures. Leaving a log is
        // enough now.
        auto error_callback = [](brillo::Error* error) {
          LOG(ERROR) << "SetVpnLockdown failed: " << error->GetMessage();
        };
        proxy->SetVpnLockdownAsync(request, success_callback,
                                   base::BindOnce(error_callback));
      },
      proxy_.get(), request));
}

base::ScopedFD ClientImpl::RedirectDns(
    Client::DnsRedirectionRequestType type,
    const std::string& input_ifname,
    const std::string& proxy_address,
    const std::vector<std::string>& nameservers,
    const std::string& host_ifname) {
  SetDnsRedirectionRuleRequest request;
  request.set_type(ConvertDnsRedirectionRequestType(type));
  request.set_input_ifname(input_ifname);
  request.set_proxy_address(proxy_address);
  request.set_host_ifname(host_ifname);
  for (const auto& nameserver : nameservers) {
    request.add_nameservers(nameserver);
  }

  // Prepare an fd pair and append one fd directly after the serialized request.
  auto [fd_local, fd_remote] = CreateLifelineFd();
  if (!fd_local.is_valid()) {
    LOG(ERROR) << "Cannot send SetDnsRedirectionRuleRequest message to "
                  "patchpanel: no lifeline fd";
    return {};
  }

  SetDnsRedirectionRuleResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const SetDnsRedirectionRuleRequest& request, base::ScopedFD fd_remote,
         SetDnsRedirectionRuleResponse* response, brillo::ErrorPtr* error) {
        return proxy->SetDnsRedirectionRule(request, fd_remote, response,
                                            error);
      },
      proxy_.get(), request, std::move(fd_remote), &response, &error));
  if (!result) {
    LOG(ERROR) << "SetDnsRedirectionRule failed: " << error->GetMessage();
    return {};
  }

  if (!response.success()) {
    LOG(ERROR) << "SetDnsRedirectionRuleRequest failed " << request;
    return {};
  }
  return std::move(fd_local);
}

std::vector<Client::VirtualDevice> ClientImpl::GetDevices() {
  // TODO(b/284797476): Add a DBus service in dns-proxy to let patchpanel push
  // information to dns-proxy.
  GetDevicesResponse response;
  brillo::ErrorPtr error;
  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, GetDevicesResponse* response,
         brillo::ErrorPtr* error) {
        return proxy->GetDevices({}, response, error);
      },
      proxy_.get(), &response, &error));
  if (!result) {
    LOG(ERROR) << "GetDevices failed: " << error->GetMessage();
    return {};
  }

  std::vector<Client::VirtualDevice> devices;
  for (const auto& d : response.devices()) {
    const auto device = ConvertVirtualDevice(d);
    if (device) {
      devices.push_back(*device);
    }
  }
  return devices;
}

void ClientImpl::RegisterVirtualDeviceEventHandler(
    VirtualDeviceEventHandler handler) {
  proxy_->RegisterNetworkDeviceChangedSignalHandler(
      base::BindRepeating(OnNetworkDeviceChanged, std::move(handler)),
      base::BindOnce(OnSignalConnectedCallback));
}

void ClientImpl::RegisterNeighborReachabilityEventHandler(
    NeighborReachabilityEventHandler handler) {
  proxy_->RegisterNeighborReachabilityEventSignalHandler(
      base::BindRepeating(OnNeighborReachabilityEvent, std::move(handler)),
      base::BindOnce(OnSignalConnectedCallback));
}

bool ClientImpl::CreateTetheredNetwork(
    const std::string& downstream_ifname,
    const std::string& upstream_ifname,
    const std::optional<DHCPOptions>& dhcp_options,
    const std::optional<UplinkIPv6Configuration>& uplink_ipv6_config,
    const std::optional<int>& mtu,
    CreateTetheredNetworkCallback callback) {
  TetheredNetworkRequest request;
  request.set_ifname(downstream_ifname);
  request.set_upstream_ifname(upstream_ifname);
  if (mtu) {
    request.set_mtu(*mtu);
  }
  if (dhcp_options.has_value()) {
    auto* ipv4_config = request.mutable_ipv4_config();
    ipv4_config->set_use_dhcp(true);
    for (const auto& dns_server : dhcp_options->dns_server_addresses) {
      ipv4_config->add_dns_servers(dns_server.ToByteString());
    }
    for (const auto& domain_search : dhcp_options->domain_search_list) {
      ipv4_config->add_domain_searches(domain_search);
    }
    if (dhcp_options->is_android_metered) {
      auto options = ipv4_config->add_options();
      // RFC 3925 defines the DHCP option 43 is Vendor Specific.
      options->set_code(43);
      options->set_content("ANDROID_METERED");
    }
  }
  request.set_enable_ipv6(true);
  if (uplink_ipv6_config.has_value()) {
    auto* ipv6_config = request.mutable_uplink_ipv6_config();
    auto* uplink_ipv6_cidr = ipv6_config->mutable_uplink_ipv6_cidr();
    uplink_ipv6_cidr->set_addr(
        uplink_ipv6_config->uplink_address.address().ToByteString());
    uplink_ipv6_cidr->set_prefix_len(
        uplink_ipv6_config->uplink_address.prefix_length());
    for (const auto& dns_server : uplink_ipv6_config->dns_server_addresses) {
      ipv6_config->add_dns_servers(dns_server.ToByteString());
    }
  }

  // Prepare an fd pair and append one fd directly after the serialized request.
  auto [fd_local, fd_remote] = CreateLifelineFd();
  if (!fd_local.is_valid()) {
    LOG(ERROR) << kCreateTetheredNetworkMethod << "(" << downstream_ifname
               << "," << upstream_ifname << "): Cannot create lifeline fds";
    return false;
  }

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const TetheredNetworkRequest& request,
         base::ScopedFD fd_local, base::ScopedFD fd_remote,
         CreateTetheredNetworkCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->CreateTetheredNetworkAsync(
            request, fd_remote,
            base::BindOnce(&OnTetheredNetworkResponse,
                           std::move(split_callback.first),
                           std::move(fd_local)),
            base::BindOnce(&OnTetheredNetworkError,
                           std::move(split_callback.second)));
      },
      proxy_.get(), request, std::move(fd_local), std::move(fd_remote),
      base::BindPostTaskToCurrentDefault(std::move(callback))));

  return true;
}

bool ClientImpl::CreateLocalOnlyNetwork(
    const std::string& ifname, CreateLocalOnlyNetworkCallback callback) {
  LocalOnlyNetworkRequest request;
  request.set_ifname(ifname);
  auto* ipv4_config = request.mutable_ipv4_config();
  ipv4_config->set_use_dhcp(true);

  // Prepare an fd pair and append one fd directly after the serialized request.
  auto [fd_local, fd_remote] = CreateLifelineFd();
  if (!fd_local.is_valid()) {
    LOG(ERROR) << kCreateLocalOnlyNetworkMethod
               << ": Cannot create lifeline fds";
    return false;
  }

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const LocalOnlyNetworkRequest& request, base::ScopedFD fd_local,
         base::ScopedFD fd_remote, CreateLocalOnlyNetworkCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->CreateLocalOnlyNetworkAsync(
            request, fd_remote,
            base::BindOnce(&OnLocalOnlyNetworkResponse,
                           std::move(split_callback.first),
                           std::move(fd_local)),
            base::BindOnce(&OnLocalOnlyNetworkError,
                           std::move(split_callback.second)));
      },
      proxy_.get(), request, std::move(fd_local), std::move(fd_remote),
      base::BindPostTaskToCurrentDefault(std::move(callback))));

  return true;
}

bool ClientImpl::GetDownstreamNetworkInfo(
    const std::string& ifname, GetDownstreamNetworkInfoCallback callback) {
  GetDownstreamNetworkInfoRequest request;
  request.set_downstream_ifname(ifname);

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const GetDownstreamNetworkInfoRequest& request,
         GetDownstreamNetworkInfoCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->GetDownstreamNetworkInfoAsync(
            request,
            base::BindOnce(&OnGetDownstreamNetworkInfoResponse,
                           std::move(split_callback.first)),
            base::BindOnce(&OnGetDownstreamNetworkInfoError,
                           std::move(split_callback.second)));
      },
      proxy_.get(), request,
      base::BindPostTaskToCurrentDefault(std::move(callback))));

  return true;
}

bool ClientImpl::ConfigureNetwork(int interface_index,
                                  std::string_view interface_name,
                                  uint32_t area,
                                  const net_base::NetworkConfig& network_config,
                                  net_base::NetworkPriority priority,
                                  NetworkTechnology technology,
                                  ConfigureNetworkCallback callback) {
  ConfigureNetworkRequest request;
  request.set_technology(ConvertNetworkTechnology(technology));
  request.set_ifindex(interface_index);
  request.set_ifname(std::string(interface_name));
  request.set_area(area);
  auto request_priority = request.mutable_priority();
  request_priority->set_is_primary_logical(priority.is_primary_logical);
  request_priority->set_is_primary_physical(priority.is_primary_physical);
  request_priority->set_is_primary_for_dns(priority.is_primary_for_dns);
  request_priority->set_ranking_order(priority.ranking_order);

  SerializeNetworkConfig(network_config, request.mutable_network_config());

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy,
         const ConfigureNetworkRequest& request,
         std::string_view interface_name, ConfigureNetworkCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->ConfigureNetworkAsync(
            request,
            base::BindOnce(&OnConfigureNetworkResponse,
                           std::move(split_callback.first),
                           std::string(interface_name)),
            base::BindOnce(&OnConfigureNetworkError,
                           std::move(split_callback.second),
                           std::string(interface_name)));
      },
      proxy_.get(), request, interface_name,
      base::BindPostTaskToCurrentDefault(std::move(callback))));
  return true;
}

bool ClientImpl::SendSetFeatureFlagRequest(FeatureFlag flag, bool enable) {
  SetFeatureFlagRequest request;
  request.set_enabled(enable);
  request.set_flag(ConvertFeatureFlag(flag));

  SetFeatureFlagResponse response;
  brillo::ErrorPtr error;

  const bool result = RunOnDBusThreadSync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const SetFeatureFlagRequest& request,
         SetFeatureFlagResponse* response, brillo::ErrorPtr* error) {
        return proxy->SetFeatureFlag(request, response, error);
      },
      proxy_.get(), request, &response, &error));

  if (!result) {
    LOG(ERROR) << "Failed to set feature flag of " << flag << ": "
               << error->GetMessage();
    return false;
  }

  return true;
}

bool ClientImpl::TagSocket(base::ScopedFD fd,
                           std::optional<int> network_id,
                           std::optional<VpnRoutingPolicy> vpn_policy,
                           std::optional<TrafficAnnotation> traffic_annotation,
                           TagSocketCallback callback) {
  TagSocketRequest request;
  if (network_id.has_value()) {
    request.set_network_id(network_id.value());
  }
  if (vpn_policy.has_value()) {
    request.set_vpn_policy(ConvertVpnRoutingPolicy(vpn_policy.value()));
  }
  if (traffic_annotation.has_value()) {
    auto annotation = request.mutable_traffic_annotation();
    annotation->set_host_id(
        ConvertTrafficAnnotationId(traffic_annotation.value().id));
  }

  TagSocketResponse response;
  brillo::ErrorPtr error;

  RunOnDBusThreadAsync(base::BindOnce(
      [](PatchPanelProxyInterface* proxy, const TagSocketRequest& request,
         base::ScopedFD fd, TagSocketCallback callback) {
        auto split_callback = SplitOnceCallback(std::move(callback));
        proxy->TagSocketAsync(request, fd,
                              base::BindOnce(&OnTagSocketResponse,
                                             std::move(split_callback.first)),
                              base::BindOnce(&OnTagSocketError,
                                             std::move(split_callback.second)));
      },
      proxy_.get(), request, std::move(fd),
      base::BindPostTaskToCurrentDefault(std::move(callback))));

  return true;
}

bool OnSocketAnnotation(base::WeakPtr<ClientImpl> client,
                        const Client::TrafficAnnotationId& id,
                        int fd) {
  // The callback might be still registered in the transport while the client
  // has been destroyed. Ensure the client is still valid before doing anything
  // else (see b/345769752).
  if (!client) {
    LOG(ERROR) << __func__ << ": client is not valid anymore";
    return false;
  }

  // The socket fd has to be duplicated to prevent the DBus proxy base::ScopedFD
  // to close the fd owned by curl.
  int tag_fd = dup(fd);
  if (tag_fd < 0) {
    LOG(ERROR) << __func__ << ": failed to dup socket descriptor";
    return false;
  }

  Client::TrafficAnnotation annotation(id);
  // TODO(b/331620358) use a synchronous call to a dedicated TagSocket service
  // to guarantee the socket is tagged when the call returns.
  return client->TagSocket(base::ScopedFD(tag_fd), std::nullopt, std::nullopt,
                           std::move(annotation), base::DoNothing());
}

void ClientImpl::PrepareTagSocket(
    const TrafficAnnotation& annotation,
    std::shared_ptr<brillo::http::Transport> transport) {
  // Bind OnSocketAnnotation as a RepeatingCallback with the annotation id as a
  // bound parameter.
  transport->SetSockOptCallback(base::BindRepeating(
      &OnSocketAnnotation, weak_factory_.GetWeakPtr(), annotation.id));
}

}  // namespace

void SerializeNetworkConfig(const net_base::NetworkConfig& in,
                            patchpanel::NetworkConfig* out) {
  if (in.ipv4_address) {
    auto* ipv4_address = out->mutable_ipv4_address();
    ipv4_address->set_addr(in.ipv4_address->address().ToByteString());
    ipv4_address->set_prefix_len(in.ipv4_address->prefix_length());
  }
  if (in.ipv4_broadcast) {
    out->set_ipv4_broadcast(in.ipv4_broadcast->ToByteString());
  }
  if (in.ipv4_gateway) {
    out->set_ipv4_gateway(in.ipv4_gateway->ToByteString());
  }

  for (const auto& ipv6_address : in.ipv6_addresses) {
    auto* out_addr = out->add_ipv6_addresses();
    out_addr->set_addr(ipv6_address.address().ToByteString());
    out_addr->set_prefix_len(ipv6_address.prefix_length());
  }
  if (in.ipv6_gateway) {
    out->set_ipv6_gateway(in.ipv6_gateway->ToByteString());
  }

  out->set_ipv6_blackhole_route(in.ipv6_blackhole_route);

  for (const auto& prefix : in.excluded_route_prefixes) {
    auto* out_prefix = out->add_excluded_route_prefixes();
    out_prefix->set_addr(prefix.address().ToByteString());
    out_prefix->set_prefix_len(prefix.prefix_length());
  }
  for (const auto& prefix : in.included_route_prefixes) {
    auto* out_prefix = out->add_included_route_prefixes();
    out_prefix->set_addr(prefix.address().ToByteString());
    out_prefix->set_prefix_len(prefix.prefix_length());
  }
  for (const auto& route : in.rfc3442_routes) {
    auto* out_route = out->add_rfc3442_routes();
    auto* out_prefix = out_route->mutable_prefix();
    out_prefix->set_addr(route.first.address().ToByteString());
    out_prefix->set_prefix_len(route.first.prefix_length());
    out_route->set_gateway(route.second.ToByteString());
  }

  for (const auto& dns : in.dns_servers) {
    out->add_dns_servers(dns.ToByteString());
  }
  for (const auto& dnssl : in.dns_search_domains) {
    out->add_dns_search_domains(dnssl);
  }
  if (in.mtu) {
    out->set_mtu(*in.mtu);
  }

  if (in.captive_portal_uri) {
    out->set_captive_portal_uri(in.captive_portal_uri->ToString());
  }
}

// static
std::unique_ptr<Client> Client::New() {
  dbus::Bus::Options opts;
  opts.bus_type = dbus::Bus::SYSTEM;
  scoped_refptr<dbus::Bus> bus(new dbus::Bus(std::move(opts)));

  if (!bus->Connect()) {
    LOG(ERROR) << "Failed to connect to system bus";
    return nullptr;
  }

  auto proxy = std::make_unique<org::chromium::PatchPanelProxy>(bus);
  if (!proxy) {
    LOG(ERROR) << "Failed to create proxy";
    return nullptr;
  }

  return std::make_unique<ClientImpl>(std::move(bus), std::move(proxy),
                                      /*owns_bus=*/true);
}

// static
std::unique_ptr<Client> Client::New(const scoped_refptr<dbus::Bus>& bus) {
  auto proxy = std::make_unique<org::chromium::PatchPanelProxy>(bus);
  if (!proxy) {
    LOG(ERROR) << "Failed to create proxy";
    return nullptr;
  }
  return std::make_unique<ClientImpl>(bus, std::move(proxy),
                                      /*owns_bus=*/false);
}

// static
std::unique_ptr<Client> Client::NewForTesting(
    scoped_refptr<dbus::Bus> bus,
    std::unique_ptr<org::chromium::PatchPanelProxyInterface> proxy) {
  return std::make_unique<ClientImpl>(std::move(bus), std::move(proxy),
                                      /*owns_bus=*/false);
}

// static
bool Client::IsArcGuest(Client::GuestType guest_type) {
  switch (guest_type) {
    case Client::GuestType::kArcContainer:
    case Client::GuestType::kArcVm:
      return true;
    default:
      return false;
  }
}

// static
std::string Client::TrafficSourceName(
    patchpanel::Client::TrafficSource source) {
  return patchpanel::TrafficCounter::Source_Name(ConvertTrafficSource(source));
}

// static
std::string Client::ProtocolName(
    patchpanel::Client::FirewallRequestProtocol protocol) {
  return patchpanel::ModifyPortRuleRequest::Protocol_Name(
      ConvertFirewallRequestProtocol(protocol));
}

// static
std::string Client::NeighborRoleName(patchpanel::Client::NeighborRole role) {
  return NeighborReachabilityEventSignal::Role_Name(ConvertNeighborRole(role));
}

// static
std::string Client::NeighborStatusName(
    patchpanel::Client::NeighborStatus status) {
  return NeighborReachabilityEventSignal::EventType_Name(
      ConvertNeighborStatus(status));
}

bool Client::TrafficVector::operator==(
    const Client::TrafficVector& that) const = default;

Client::TrafficVector& Client::TrafficVector::operator+=(
    const TrafficVector& that) {
  rx_bytes += that.rx_bytes;
  tx_bytes += that.tx_bytes;
  rx_packets += that.rx_packets;
  tx_packets += that.tx_packets;
  return *this;
}

Client::TrafficVector& Client::TrafficVector::operator-=(
    const TrafficVector& that) {
  rx_bytes -= that.rx_bytes;
  tx_bytes -= that.tx_bytes;
  rx_packets -= that.rx_packets;
  tx_packets -= that.tx_packets;
  return *this;
}

Client::TrafficVector Client::TrafficVector::operator+(
    const TrafficVector& that) const {
  auto r = *this;
  r += that;
  return r;
}

Client::TrafficVector Client::TrafficVector::operator-(
    const TrafficVector& that) const {
  auto r = *this;
  r -= that;
  return r;
}

Client::TrafficVector Client::TrafficVector::operator-() const {
  auto r = *this;
  r.rx_bytes = -r.rx_bytes;
  r.tx_bytes = -r.tx_bytes;
  r.rx_packets = -r.rx_packets;
  r.tx_packets = -r.tx_packets;
  return r;
}

bool Client::TrafficCounter::operator==(
    const Client::TrafficCounter& rhs) const = default;

BRILLO_EXPORT std::ostream& operator<<(
    std::ostream& stream, const Client::NeighborReachabilityEvent& event) {
  return stream << "{ifindex: " << event.ifindex
                << ", ip_address: " << event.ip_addr
                << ", role: " << Client::NeighborRoleName(event.role)
                << ", status: " << Client::NeighborStatusName(event.status)
                << "}";
}

BRILLO_EXPORT std::ostream& operator<<(
    std::ostream& stream, const Client::NetworkTechnology& technology) {
  switch (technology) {
    case Client::NetworkTechnology::kCellular:
      return stream << "Cellular";
    case Client::NetworkTechnology::kEthernet:
      return stream << "Ethernet";
    case Client::NetworkTechnology::kVPN:
      return stream << "VPN";
    case Client::NetworkTechnology::kWiFi:
      return stream << "WiFi";
  }
}

BRILLO_EXPORT std::ostream& operator<<(
    std::ostream& stream, const Client::TrafficSource& traffic_source) {
  switch (traffic_source) {
    case patchpanel::Client::TrafficSource::kUnknown:
      return stream << "Unknown";
    case patchpanel::Client::TrafficSource::kChrome:
      return stream << "Chrome";
    case patchpanel::Client::TrafficSource::kUser:
      return stream << "User";
    case patchpanel::Client::TrafficSource::kUpdateEngine:
      return stream << "UE";
    case patchpanel::Client::TrafficSource::kSystem:
      return stream << "System";
    case patchpanel::Client::TrafficSource::kVpn:
      return stream << "VPN";
    case patchpanel::Client::TrafficSource::kArc:
      return stream << "ARC";
    case patchpanel::Client::TrafficSource::kBorealisVM:
      return stream << "Borealis";
    case patchpanel::Client::TrafficSource::kBruschettaVM:
      return stream << "Bruschetta";
    case patchpanel::Client::TrafficSource::kCrostiniVM:
      return stream << "Crostini";
    case patchpanel::Client::TrafficSource::kParallelsVM:
      return stream << "Parallels";
    case patchpanel::Client::TrafficSource::kTethering:
      return stream << "Tethering";
    case patchpanel::Client::TrafficSource::kWiFiDirect:
      return stream << "WiFi Direct";
    case patchpanel::Client::TrafficSource::kWiFiLOHS:
      return stream << "WiFi LOHS";
  }
}

BRILLO_EXPORT std::ostream& operator<<(
    std::ostream& stream, const Client::TrafficVector& traffic_vector) {
  return stream << "[rx=" << traffic_vector.rx_bytes
                << ", tx=" << traffic_vector.tx_bytes << "]";
}

}  // namespace patchpanel
