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

#include "shill/modem.h"

#include <base/file_util.h>
#include <base/stl_util.h>
#include <ModemManager/ModemManager.h>

#include "shill/cellular.h"
#include "shill/device_info.h"

using std::string;

namespace shill {

namespace {

// The default place where the system keeps symbolic links for network device
const char kDefaultNetfilesPath[] = "/sys/class/net";

}  // namespace

Modem1::Modem1(const string &owner,
               const string &service,
               const string &path,
               ControlInterface *control_interface,
               EventDispatcher *dispatcher,
               Metrics *metrics,
               Manager *manager,
               CellularOperatorInfo *cellular_operator_info,
               mobile_provider_db *provider_db)
    : Modem(owner, service, path, control_interface, dispatcher, metrics,
            manager, cellular_operator_info, provider_db),
      netfiles_path_(kDefaultNetfilesPath) {
}

Modem1::~Modem1() {}

bool Modem1::GetLinkName(const DBusPropertiesMap &modem_props,
                         string *name) const {
  string device_prop;
  if (!DBusProperties::GetString(modem_props,
                                 MM_MODEM_PROPERTY_DEVICE,
                                 &device_prop)) {
    LOG(ERROR) << "Device missing property: " << MM_MODEM_PROPERTY_DEVICE;
    return false;
  }

  if (device_prop.find(DeviceInfo::kModemPseudoDeviceNamePrefix) == 0) {
    *name = device_prop;
    return true;
  }

  // |device_prop| will be a sysfs path such as:
  //  /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-2
  FilePath device_path(device_prop);

  // Each entry in |netfiles_path_" (typically /sys/class/net)
  // has the name of a network interface and is a symlink into the
  // actual device structure:
  //  eth0 -> ../../devices/pci0000:00/0000:00:1c.5/0000:01:00.0/net/eth0
  // Iterate over all of these and see if any of them point into
  // subdirectories of the sysfs path from the Device property.
  // FileEnumerator warns that it is a blocking interface; that
  // shouldn't be a problem here.
  file_util::FileEnumerator netfiles(netfiles_path_,
                                     false,  // don't recurse
                                     file_util::FileEnumerator::DIRECTORIES);
  for (FilePath link = netfiles.Next(); !link.empty(); link = netfiles.Next()) {
    FilePath target;
    if (!file_util::ReadSymbolicLink(link, &target))
      continue;
    if (!target.IsAbsolute())
      target = netfiles_path_.Append(target);
    if (file_util::ContainsPath(device_path, target)) {
      *name = link.BaseName().value();
      return true;
    }
  }
  LOG(ERROR) << "No link name found for: " << device_prop;
  return false;
}

void Modem1::CreateDeviceMM1(const DBusInterfaceToProperties &properties) {
  Init();
  if (!ContainsKey(properties, MM_DBUS_INTERFACE_MODEM)) {
    LOG(ERROR) << "Cellular device with no modem properties";
    return;
  }
  set_type(Cellular::kTypeUniversal);

  // We cannot check the IP method to make sure it's not PPP. The IP
  // method will be checked later when the bearer object is fetched.
  CreateDeviceFromModemProperties(properties);
}

string Modem1::GetModemInterface(void) const {
  return string(MM_DBUS_INTERFACE_MODEM);
}

}  // namespace shill
