// Copyright (c) 2011 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/base/net_util.h"

#if !defined(OS_STARBOARD)
#include <sys/types.h>
#endif

#include "base/file_path.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/threading/thread_restrictions.h"
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"

#if !defined(OS_STARBOARD)
#if !defined(OS_ANDROID)
#include <ifaddrs.h>
#endif
#include <net/if.h>
#include <netinet/in.h>
#endif

#if defined(OS_ANDROID)
#include "net/android/network_library.h"
#endif

namespace net {

bool FileURLToFilePath(const GURL& url, FilePath* path) {
  *path = FilePath();
  std::string& file_path_str = const_cast<std::string&>(path->value());
  file_path_str.clear();

  if (!url.is_valid())
    return false;

  // Firefox seems to ignore the "host" of a file url if there is one. That is,
  // file://foo/bar.txt maps to /bar.txt.
  // TODO(dhg): This should probably take into account UNCs which could
  // include a hostname other than localhost or blank
  std::string old_path = url.path();

  if (old_path.empty())
    return false;

  // GURL stores strings as percent-encoded 8-bit, this will undo if possible.
  old_path = UnescapeURLComponent(old_path,
      UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);

  // Collapse multiple path slashes into a single path slash.
  std::string new_path;
  do {
    new_path = old_path;
    ReplaceSubstringsAfterOffset(&new_path, 0, "//", "/");
    old_path.swap(new_path);
  } while (new_path != old_path);

  file_path_str.assign(old_path);

  return !file_path_str.empty();
}

bool GetNetworkList(NetworkInterfaceList* networks) {
#if defined(OS_ANDROID)
  std::string network_list = android::GetNetworkList();
  StringTokenizer network_interfaces(network_list, ";");
  while (network_interfaces.GetNext()) {
    std::string network_item = network_interfaces.token();
    StringTokenizer network_tokenizer(network_item, ",");
    std::string name;
    if (!network_tokenizer.GetNext())
      continue;
    name = network_tokenizer.token();

    std::string literal_address;
    if (!network_tokenizer.GetNext())
      continue;
    literal_address = network_tokenizer.token();

    IPAddressNumber address;
    if (!ParseIPLiteralToNumber(literal_address, &address))
      continue;
    networks->push_back(NetworkInterface(name, address));
  }
  return true;
#elif defined(__LB_SHELL__) || defined(OS_STARBOARD)
  // LBShell and Starboard don't support ifaddrs.
  NOTIMPLEMENTED();
  return false;
#else
  // getifaddrs() may require IO operations.
  base::ThreadRestrictions::AssertIOAllowed();

  ifaddrs *interfaces;
  if (getifaddrs(&interfaces) < 0) {
    PLOG(ERROR) << "getifaddrs";
    return false;
  }

  // Enumerate the addresses assigned to network interfaces which are up.
  for (ifaddrs *interface = interfaces;
       interface != NULL;
       interface = interface->ifa_next) {
    // Skip loopback interfaces, and ones which are down.
    if (!(IFF_UP & interface->ifa_flags))
      continue;
    if (IFF_LOOPBACK & interface->ifa_flags)
      continue;
    // Skip interfaces with no address configured.
    struct sockaddr* addr = interface->ifa_addr;
    if (!addr)
      continue;
    // Skip loopback addresses configured on non-loopback interfaces.
    int addr_size = 0;
    if (addr->sa_family == AF_INET6) {
      struct sockaddr_in6* addr_in6 =
          reinterpret_cast<struct sockaddr_in6*>(addr);
      struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
      addr_size = sizeof(*addr_in6);
      if (IN6_IS_ADDR_LOOPBACK(sin6_addr))
        continue;
    } else if (addr->sa_family == AF_INET) {
      struct sockaddr_in* addr_in =
          reinterpret_cast<struct sockaddr_in*>(addr);
      addr_size = sizeof(*addr_in);
      if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK)
        continue;
    } else {
      // Skip non-IP addresses.
      continue;
    }
    IPEndPoint address;
    std::string name = interface->ifa_name;
    if (address.FromSockAddr(addr, addr_size)) {
      networks->push_back(NetworkInterface(name, address.address()));
    }
  }

  freeifaddrs(interfaces);

  return true;
#endif
}

}  // namespace net
