// Copyright (c) 2013 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 base::FilePath;
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,
               ModemInfo *modem_info)
    : Modem(owner, service, path, modem_info),
      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();
  uint32 capabilities = kuint32max;
  DBusInterfaceToProperties::const_iterator it =
      properties.find(MM_DBUS_INTERFACE_MODEM);
  if (it == properties.end()) {
    LOG(ERROR) << "Cellular device with no modem properties";
    return;
  }
  const DBusPropertiesMap &modem_props = it->second;
  DBusProperties::GetUint32(modem_props,
                            MM_MODEM_PROPERTY_CURRENTCAPABILITIES,
                            &capabilities);

  if ((capabilities & MM_MODEM_CAPABILITY_LTE) ||
      (capabilities & MM_MODEM_CAPABILITY_GSM_UMTS)) {
    set_type(Cellular::kTypeUniversal);
  } else if (capabilities & MM_MODEM_CAPABILITY_CDMA_EVDO) {
    set_type(Cellular::kTypeUniversalCDMA);
  } else {
    LOG(ERROR) << "Unsupported capabilities: " << capabilities;
    return;
  }

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