// 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_cdma_proxy.h"

#include "shill/cellular_error.h"
#include "shill/logging.h"

using std::string;

namespace shill {

ModemCDMAProxy::ModemCDMAProxy(
                               DBus::Connection *connection,
                               const string &path,
                               const string &service)
    : proxy_(connection, path, service) {}

ModemCDMAProxy::~ModemCDMAProxy() {}

void ModemCDMAProxy::Activate(const string &carrier, Error *error,
                              const ActivationResultCallback &callback,
                              int timeout) {
  scoped_ptr<ActivationResultCallback>
      cb(new ActivationResultCallback(callback));
  try {
    SLOG(DBus, 2) << __func__;
    proxy_.Activate(carrier, cb.get(), timeout);
    cb.release();
  } catch (const DBus::Error &e) {
    if (error)
      CellularError::FromDBusError(e, error);
  }
}

void ModemCDMAProxy::GetRegistrationState(
    Error *error,
    const RegistrationStateCallback &callback,
    int timeout) {
  scoped_ptr<RegistrationStateCallback>
      cb(new RegistrationStateCallback(callback));
  try {
    SLOG(DBus, 2) << __func__;
    proxy_.GetRegistrationState(cb.get(), timeout);
    cb.release();
  } catch (const DBus::Error &e) {
    if (error)
      CellularError::FromDBusError(e, error);
  }
}

void ModemCDMAProxy::GetSignalQuality(Error *error,
                                      const SignalQualityCallback &callback,
                                      int timeout) {
  scoped_ptr<SignalQualityCallback> cb(new SignalQualityCallback(callback));
  try {
    SLOG(DBus, 2) << __func__;
    proxy_.GetSignalQuality(cb.get(), timeout);
    cb.release();
  } catch (const DBus::Error &e) {
    if (error)
      CellularError::FromDBusError(e, error);
  }
}

const string ModemCDMAProxy::MEID() {
  LOG(INFO) << "ModemCDMAProxy::" << __func__;
  SLOG(DBus, 2) << __func__;
  try {
    return proxy_.Meid();
  } catch (const DBus::Error &e) {
    LOG(FATAL) << "DBus exception: " << e.name() << ": " << e.what();
    return string();  // Make the compiler happy.
  }
}

void ModemCDMAProxy::set_activation_state_callback(
    const ActivationStateSignalCallback &callback) {
  proxy_.set_activation_state_callback(callback);
}

void ModemCDMAProxy::set_signal_quality_callback(
    const SignalQualitySignalCallback &callback) {
  proxy_.set_signal_quality_callback(callback);
}

void ModemCDMAProxy::set_registration_state_callback(
    const RegistrationStateSignalCallback &callback) {
  proxy_.set_registration_state_callback(callback);
}

ModemCDMAProxy::Proxy::Proxy(DBus::Connection *connection,
                             const string &path,
                             const string &service)
    : DBus::ObjectProxy(*connection, path, service.c_str()) {}

ModemCDMAProxy::Proxy::~Proxy() {}

void ModemCDMAProxy::Proxy::set_activation_state_callback(
    const ActivationStateSignalCallback &callback) {
  activation_state_callback_ = callback;
}

void ModemCDMAProxy::Proxy::set_signal_quality_callback(
    const SignalQualitySignalCallback &callback) {
  signal_quality_callback_ = callback;
}

void ModemCDMAProxy::Proxy::set_registration_state_callback(
    const RegistrationStateSignalCallback &callback) {
  registration_state_callback_ = callback;
}

void ModemCDMAProxy::Proxy::ActivationStateChanged(
    const uint32 &activation_state,
    const uint32 &activation_error,
    const DBusPropertiesMap &status_changes) {
  SLOG(DBus, 2) << __func__ << "(" << activation_state << ", "
                << activation_error << ")";
  activation_state_callback_.Run(activation_state,
                                  activation_error,
                                  status_changes);
}

void ModemCDMAProxy::Proxy::SignalQuality(const uint32 &quality) {
  SLOG(DBus, 2) << __func__ << "(" << quality << ")";
  signal_quality_callback_.Run(quality);
}

void ModemCDMAProxy::Proxy::RegistrationStateChanged(
    const uint32 &cdma_1x_state,
    const uint32 &evdo_state) {
  SLOG(DBus, 2) << __func__ << "(" << cdma_1x_state << ", "
                << evdo_state << ")";
  registration_state_callback_.Run(cdma_1x_state, evdo_state);
}

void ModemCDMAProxy::Proxy::ActivateCallback(const uint32_t &status,
                                             const DBus::Error &dberror,
                                             void *data) {
  SLOG(DBus, 2) << __func__ << "(" << status << ")";
  scoped_ptr<ActivationResultCallback> callback(
      reinterpret_cast<ActivationResultCallback *>(data));
  Error error;
  CellularError::FromDBusError(dberror, &error);
  callback->Run(status, error);
}

void ModemCDMAProxy::Proxy::GetRegistrationStateCallback(
    const uint32 &state_1x, const uint32 &state_evdo,
    const DBus::Error &dberror, void *data) {
  SLOG(DBus, 2) << __func__ << "(" << state_1x << ", " << state_evdo << ")";
  scoped_ptr<RegistrationStateCallback> callback(
      reinterpret_cast<RegistrationStateCallback *>(data));
  Error error;
  CellularError::FromDBusError(dberror, &error);
  callback->Run(state_1x, state_evdo, error);
}


void ModemCDMAProxy::Proxy::GetSignalQualityCallback(const uint32 &quality,
                                                     const DBus::Error &dberror,
                                                     void *data) {
  SLOG(DBus, 2) << __func__ << "(" << quality << ")";
  scoped_ptr<SignalQualityCallback> callback(
      reinterpret_cast<SignalQualityCallback *>(data));
  Error error;
  CellularError::FromDBusError(dberror, &error);
  callback->Run(quality, error);
}

}  // namespace shill
