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

#include "net/socket/socket_net_log_params.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_endpoint.h"
#include "net/log/net_log_capture_mode.h"

namespace net {

namespace {

base::Value NetLogSocketErrorCallback(int net_error,
                                      int os_error,
                                      NetLogCaptureMode /* capture_mode */) {
  base::DictionaryValue dict;
  dict.SetInteger("net_error", net_error);
  dict.SetInteger("os_error", os_error);
  return std::move(dict);
}

base::Value NetLogHostPortPairCallback(const HostPortPair* host_and_port,
                                       NetLogCaptureMode /* capture_mode */) {
  base::DictionaryValue dict;
  dict.SetString("host_and_port", host_and_port->ToString());
  return std::move(dict);
}

base::Value NetLogIPEndPointCallback(const IPEndPoint* address,
                                     NetLogCaptureMode /* capture_mode */) {
  base::DictionaryValue dict;
  dict.SetString("address", address->ToString());
  return std::move(dict);
}

base::Value NetLogSourceAddressCallback(const struct sockaddr* net_address,
                                        socklen_t address_len,
                                        NetLogCaptureMode /* capture_mode */) {
  base::DictionaryValue dict;
  IPEndPoint ipe;
  bool result = ipe.FromSockAddr(net_address, address_len);
  DCHECK(result);
  dict.SetString("source_address", ipe.ToString());
  return std::move(dict);
}

}  // namespace

NetLogParametersCallback CreateNetLogSocketErrorCallback(int net_error,
                                                         int os_error) {
  return base::Bind(&NetLogSocketErrorCallback, net_error, os_error);
}

NetLogParametersCallback CreateNetLogHostPortPairCallback(
    const HostPortPair* host_and_port) {
  return base::Bind(&NetLogHostPortPairCallback, host_and_port);
}

NetLogParametersCallback CreateNetLogIPEndPointCallback(
    const IPEndPoint* address) {
  return base::Bind(&NetLogIPEndPointCallback, address);
}

NetLogParametersCallback CreateNetLogSourceAddressCallback(
    const struct sockaddr* net_address,
    socklen_t address_len) {
  return base::Bind(&NetLogSourceAddressCallback, net_address, address_len);
}

}  // namespace net
