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

#include <chromeos/dbus/service_constants.h>
#include <base/stringprintf.h>
#include <base/string_number_conversions.h>
#include <base/string_util.h>

#include "shill/cellular_operator_info.h"
#include "shill/dbus_properties_proxy_interface.h"
#include "shill/error.h"
#include "shill/logging.h"
#include "shill/pending_activation_store.h"
#include "shill/proxy_factory.h"

#ifdef MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN
#error "Do not include mm-modem.h"
#endif

using base::UintToString;

using std::string;
using std::vector;

namespace shill {

namespace {

const char kPhoneNumber[] = "#777";
const char kPropertyConnectNumber[] = "number";

string FormattedSID(const string &sid) {
  return "[SID=" + sid + "]";
}

}  // namespace

// static
unsigned int
CellularCapabilityUniversalCDMA::friendly_service_name_id_cdma_ = 0;

CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA(
    Cellular *cellular,
    ProxyFactory *proxy_factory,
    ModemInfo *modem_info)
    : CellularCapabilityUniversal(cellular,
                                  proxy_factory,
                                  modem_info),
      weak_cdma_ptr_factory_(this),
      activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
      cdma_1x_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
      cdma_evdo_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
      nid_(0),
      sid_(0) {
  SLOG(Cellular, 2) << "Cellular capability constructed: Universal CDMA";
  // TODO(armansito): Update PRL for activation over cellular.
  // See crbug.com/197330.
}

void CellularCapabilityUniversalCDMA::InitProxies() {
  SLOG(Cellular, 2) << __func__;
  modem_cdma_proxy_.reset(
      proxy_factory()->CreateMM1ModemModemCdmaProxy(cellular()->dbus_path(),
                                                    cellular()->dbus_owner()));
  modem_cdma_proxy_->set_activation_state_callback(
      Bind(&CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal,
      weak_cdma_ptr_factory_.GetWeakPtr()));
  CellularCapabilityUniversal::InitProxies();
}

void CellularCapabilityUniversalCDMA::ReleaseProxies() {
  SLOG(Cellular, 2) << __func__;
  modem_cdma_proxy_.reset();
  CellularCapabilityUniversal::ReleaseProxies();
}

void CellularCapabilityUniversalCDMA::Activate(
    const string &carrier,
    Error *error,
    const ResultCallback &callback) {
  // Currently activation over the cellular network is not supported using
  // ModemManager-next. Service activation is currently carried through over
  // non-cellular networks and only the final step of the OTA activation
  // procedure ("automatic activation") is performed by this class.
  OnUnsupportedOperation(__func__, error);
}

void CellularCapabilityUniversalCDMA::CompleteActivation(Error *error) {
  SLOG(Cellular, 2) << __func__;
  if (cellular()->state() < Cellular::kStateEnabled) {
    Error::PopulateAndLog(error, Error::kInvalidArguments,
                          "Unable to activate in state " +
                          Cellular::GetStateString(cellular()->state()));
    return;
  }
  ActivateAutomatic();
}

void CellularCapabilityUniversalCDMA::ActivateAutomatic() {
  if (activation_code_.empty()) {
    SLOG(Cellular, 2) << "OTA activation cannot be run in the presence of no "
                      << "activation code.";
    return;
  }
  PendingActivationStore::State state =
      modem_info()->pending_activation_store()->GetActivationState(
          PendingActivationStore::kIdentifierMEID, meid());
  if (state == PendingActivationStore::kStatePending) {
    SLOG(Cellular, 2) << "There's already a pending activation. Ignoring.";
    return;
  }
  if (state == PendingActivationStore::kStateActivated) {
    SLOG(Cellular, 2) << "A call to OTA activation has already completed "
                      << "successfully. Ignoring.";
    return;
  }

  // Mark as pending activation, so that shill can recover if anything fails
  // during OTA activation.
  modem_info()->pending_activation_store()->SetActivationState(
      PendingActivationStore::kIdentifierMEID,
      meid(),
      PendingActivationStore::kStatePending);

  // Initiate OTA activation.
  ResultCallback activation_callback =
    Bind(&CellularCapabilityUniversalCDMA::OnActivateReply,
         weak_cdma_ptr_factory_.GetWeakPtr(),
         ResultCallback());

  Error error;
  modem_cdma_proxy_->Activate(
      activation_code_, &error, activation_callback, kTimeoutActivate);
}

void CellularCapabilityUniversalCDMA::UpdatePendingActivationState() {
  SLOG(Cellular, 2) << __func__;
  if (IsActivated()) {
    SLOG(Cellular, 3) << "CDMA service activated. Clear store.";
    modem_info()->pending_activation_store()->RemoveEntry(
        PendingActivationStore::kIdentifierMEID, meid());
    return;
  }
  PendingActivationStore::State state =
      modem_info()->pending_activation_store()->GetActivationState(
          PendingActivationStore::kIdentifierMEID, meid());
  if (IsActivating() && state != PendingActivationStore::kStateFailureRetry) {
    SLOG(Cellular, 3) << "OTA activation in progress. Nothing to do.";
    return;
  }
  switch (state) {
    case PendingActivationStore::kStateFailureRetry:
      SLOG(Cellular, 3) << "OTA activation failed. Scheduling a retry.";
      cellular()->dispatcher()->PostTask(
          Bind(&CellularCapabilityUniversalCDMA::ActivateAutomatic,
               weak_cdma_ptr_factory_.GetWeakPtr()));
      break;
    case PendingActivationStore::kStateActivated:
      SLOG(Cellular, 3) << "OTA Activation has completed successfully. "
                        << "Waiting for activation state update to finalize.";
      break;
    default:
      break;
  }
}

bool CellularCapabilityUniversalCDMA::IsServiceActivationRequired() const {
  // If there is no online payment portal information, it's safer to assume
  // the service does not require activation.
  if (!modem_info()->cellular_operator_info())
    return false;

  const CellularService::OLP *olp =
      modem_info()->cellular_operator_info()->GetOLPBySID(UintToString(sid_));
  if (!olp)
    return false;

  // We could also use the MDN to determine whether or not the service is
  // activated, however, the CDMA ActivatonState property is a more absolute
  // and fine-grained indicator of activation status.
  return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED);
}

bool CellularCapabilityUniversalCDMA::IsActivated() const {
  return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED);
}

void CellularCapabilityUniversalCDMA::OnServiceCreated() {
  SLOG(Cellular, 2) << __func__;
  // TODO (armansito): Set storage identifier here  based on the superclass
  // implementation.
  UpdateServiceActivationStateProperty();
  UpdateServingOperator();
  HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
  UpdatePendingActivationState();
  UpdateOLP();
}

void CellularCapabilityUniversalCDMA::UpdateServiceActivationStateProperty() {
  bool activation_required = IsServiceActivationRequired();
  cellular()->service()->SetActivateOverNonCellularNetwork(activation_required);
  string activation_state;
  if (IsActivating())
      activation_state = flimflam::kActivationStateActivating;
  else if (activation_required)
      activation_state = flimflam::kActivationStateNotActivated;
  else
      activation_state = flimflam::kActivationStateActivated;
  cellular()->service()->SetActivationState(activation_state);
}

void CellularCapabilityUniversalCDMA::UpdateOLP() {
  SLOG(Cellular, 2) << __func__;

  const CellularOperatorInfo *cellular_operator_info =
      modem_info()->cellular_operator_info();
  if (!cellular_operator_info)
    return;

  string sid_string = UintToString(sid_);
  const CellularOperatorInfo::CellularOperator *cellular_operator =
      cellular_operator_info->GetCellularOperatorBySID(sid_string);
  if (!cellular_operator)
    return;

  const CellularService::OLP *result =
      cellular_operator_info->GetOLPBySID(sid_string);
  if (!result)
    return;

  CellularService::OLP olp;
  olp.CopyFrom(*result);
  string post_data = olp.GetPostData();
  ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", esn());
  ReplaceSubstringsAfterOffset(&post_data, 0, "${mdn}",
                               GetMdnForOLP(*cellular_operator));
  ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", meid());
  olp.SetPostData(post_data);
  if (cellular()->service().get())
    cellular()->service()->SetOLP(olp);
}

void CellularCapabilityUniversalCDMA::GetProperties() {
  SLOG(Cellular, 2) << __func__;
  CellularCapabilityUniversal::GetProperties();

  scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
      proxy_factory()->CreateDBusPropertiesProxy(cellular()->dbus_path(),
                                                 cellular()->dbus_owner()));
  DBusPropertiesMap properties(
      properties_proxy->GetAll(MM_DBUS_INTERFACE_MODEM_MODEMCDMA));
  OnModemCDMAPropertiesChanged(properties, vector<string>());
}

string CellularCapabilityUniversalCDMA::CreateFriendlyServiceName() {
  SLOG(Cellular, 2) << __func__ << ": " << GetRoamingStateString();

  if (provider_.GetCode().empty()) {
    UpdateOperatorInfo();
  }

  string name = provider_.GetName();
  if (!name.empty()) {
    // TODO(armansito): We may need to show the provider name in a
    // specific way if roaming.
    return name;
  }

  string code = provider_.GetCode();
  if (!code.empty()) {
    return "cellular_sid_" + code;
  }

  return base::StringPrintf("CDMANetwork%u", friendly_service_name_id_cdma_++);
}

void CellularCapabilityUniversalCDMA::UpdateOperatorInfo() {
  SLOG(Cellular, 2) << __func__;

  if (sid_ == 0 || !modem_info()->cellular_operator_info()) {
    SLOG(Cellular, 2) << "No provider is currently available.";
    provider_.SetCode("");
    return;
  }

  string sid = UintToString(sid_);
  const CellularOperatorInfo::CellularOperator *provider =
      modem_info()->cellular_operator_info()->GetCellularOperatorBySID(sid);
  if (!provider) {
    SLOG(Cellular, 2) << "CDMA provider with "
                      << FormattedSID(sid)
                      << " not found.";
    return;
  }

  if (!provider->name_list().empty()) {
    provider_.SetName(provider->name_list()[0].name);
  }
  provider_.SetCode(sid);
  provider_.SetCountry(provider->country());

  activation_code_ = provider->activation_code();

  // TODO(armansito): The CDMA interface only returns information about the
  // current serving carrier, so for now both the home provider and the
  // serving operator will be the same in case of roaming. We should figure
  // out if there is a way to (and whether or not it is necessary to)
  // determine if we're roaming.
  cellular()->set_home_provider(provider_);

  UpdateServingOperator();
}

void CellularCapabilityUniversalCDMA::UpdateServingOperator() {
  SLOG(Cellular, 2) << __func__;
  if (cellular()->service().get()) {
    cellular()->service()->SetServingOperator(cellular()->home_provider());
  }
}

void CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal(
    uint32 activation_state,
    uint32 activation_error,
    const DBusPropertiesMap &status_changes) {
  SLOG(Cellular, 2) << __func__;

  activation_state_ =
      static_cast<MMModemCdmaActivationState>(activation_state);

  string value;
  if (DBusProperties::GetString(status_changes, "mdn", &value))
    set_mdn(value);
  if (DBusProperties::GetString(status_changes, "min", &value))
    set_min(value);

  SLOG(Cellular, 2) << "Activation state: "
                    << GetActivationStateString(activation_state_);

  HandleNewActivationStatus(activation_error);
  UpdatePendingActivationState();
}

void CellularCapabilityUniversalCDMA::OnActivateReply(
    const ResultCallback &callback,
    const Error &error) {
  SLOG(Cellular, 2) << __func__;
  if (error.IsSuccess()) {
    LOG(INFO) << "Activation completed successfully.";
    modem_info()->pending_activation_store()->SetActivationState(
        PendingActivationStore::kIdentifierMEID,
        meid(),
        PendingActivationStore::kStateActivated);
  } else {
    LOG(ERROR) << "Activation failed with error: " << error;
    modem_info()->pending_activation_store()->SetActivationState(
        PendingActivationStore::kIdentifierMEID,
        meid(),
        PendingActivationStore::kStateFailureRetry);
  }
  UpdatePendingActivationState();

  // CellularCapabilityUniversalCDMA::ActivateAutomatic passes a dummy
  // ResultCallback when it calls Activate on the proxy object, in which case
  // |callback.is_null()| will return true.
  if (!callback.is_null())
    callback.Run(error);
}

void CellularCapabilityUniversalCDMA::HandleNewActivationStatus(uint32 error) {
  SLOG(Cellular, 2) << __func__ << "(" << error << ")";
  if (!cellular()->service().get()) {
    LOG(ERROR) << "In " << __func__ << "(): service is null.";
    return;
  }
  SLOG(Cellular, 2) << "Activation State: " << activation_state_;
  cellular()->service()->SetActivationState(
      GetActivationStateString(activation_state_));
  cellular()->service()->set_error(GetActivationErrorString(error));
  UpdateOLP();
}

// static
string CellularCapabilityUniversalCDMA::GetActivationStateString(
    uint32 state) {
  switch (state) {
    case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
      return flimflam::kActivationStateActivated;
    case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
      return flimflam::kActivationStateActivating;
    case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
      return flimflam::kActivationStateNotActivated;
    case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
      return flimflam::kActivationStatePartiallyActivated;
    default:
      return flimflam::kActivationStateUnknown;
  }
}

// static
string CellularCapabilityUniversalCDMA::GetActivationErrorString(
    uint32 error) {
  switch (error) {
    case MM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
      return flimflam::kErrorNeedEvdo;
    case MM_CDMA_ACTIVATION_ERROR_ROAMING:
      return flimflam::kErrorNeedHomeNetwork;
    case MM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT:
    case MM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED:
    case MM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED:
      return flimflam::kErrorOtaspFailed;
    case MM_CDMA_ACTIVATION_ERROR_NONE:
      return "";
    case MM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
    default:
      return flimflam::kErrorActivationFailed;
  }
}

void CellularCapabilityUniversalCDMA::Register(const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::RegisterOnNetwork(
    const string &network_id,
    Error *error,
    const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

bool CellularCapabilityUniversalCDMA::IsActivating() const {
  PendingActivationStore::State state =
      modem_info()->pending_activation_store()->GetActivationState(
          PendingActivationStore::kIdentifierMEID, meid());
  return (state == PendingActivationStore::kStatePending) ||
      (state == PendingActivationStore::kStateFailureRetry) ||
      (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING);
}

bool CellularCapabilityUniversalCDMA::IsRegistered() {
  return (cdma_1x_registration_state_ ==
              MM_MODEM_CDMA_REGISTRATION_STATE_HOME ||
          cdma_1x_registration_state_ ==
              MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING ||
          cdma_evdo_registration_state_ ==
              MM_MODEM_CDMA_REGISTRATION_STATE_HOME ||
          cdma_evdo_registration_state_ ==
              MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING);
}

void CellularCapabilityUniversalCDMA::SetUnregistered(bool /*searching*/) {
  cdma_1x_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
  cdma_evdo_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
}

void CellularCapabilityUniversalCDMA::SetupConnectProperties(
    DBusPropertiesMap *properties) {
  (*properties)[kPropertyConnectNumber].writer().append_string(
      kPhoneNumber);
}

void CellularCapabilityUniversalCDMA::RequirePIN(
    const string &pin, bool require,
    Error *error, const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::EnterPIN(
    const string &pin,
    Error *error,
    const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::UnblockPIN(
    const string &unblock_code,
    const string &pin,
    Error *error,
    const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::ChangePIN(
    const string &old_pin, const string &new_pin,
    Error *error, const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::Scan(Error *error,
                                           const ResultCallback &callback) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

void CellularCapabilityUniversalCDMA::OnSimPathChanged(
    const string &sim_path) {
  // TODO(armansito): Remove once 3GPP is implemented in its own class.
}

string CellularCapabilityUniversalCDMA::GetRoamingStateString() const {
  uint32 state = cdma_evdo_registration_state_;
  if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
    state = cdma_1x_registration_state_;
  }
  switch (state) {
    case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
    case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
      break;
    case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
      return flimflam::kRoamingStateHome;
    case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
      return flimflam::kRoamingStateRoaming;
    default:
      NOTREACHED();
  }
  return flimflam::kRoamingStateUnknown;
}

void CellularCapabilityUniversalCDMA::OnDBusPropertiesChanged(
    const string &interface,
    const DBusPropertiesMap &changed_properties,
    const vector<string> &invalidated_properties) {
  SLOG(Cellular, 2) << __func__ << "(" << interface << ")";
  if (interface == MM_DBUS_INTERFACE_MODEM_MODEMCDMA) {
    OnModemCDMAPropertiesChanged(changed_properties, invalidated_properties);
  } else {
    CellularCapabilityUniversal::OnDBusPropertiesChanged(
        interface, changed_properties, invalidated_properties);
  }
}

void CellularCapabilityUniversalCDMA::OnModemCDMAPropertiesChanged(
    const DBusPropertiesMap &properties,
    const std::vector<std::string> &/*invalidated_properties*/) {
  SLOG(Cellular, 2) << __func__;
  string str_value;
  if (DBusProperties::GetString(properties,
                                MM_MODEM_MODEMCDMA_PROPERTY_MEID,
                                &str_value))
    set_meid(str_value);
  if (DBusProperties::GetString(properties,
                                MM_MODEM_MODEMCDMA_PROPERTY_ESN,
                                &str_value))
    set_esn(str_value);

  uint32_t sid = sid_;
  uint32_t nid = nid_;
  MMModemCdmaRegistrationState state_1x = cdma_1x_registration_state_;
  MMModemCdmaRegistrationState state_evdo = cdma_evdo_registration_state_;
  bool registration_changed = false;
  uint32_t uint_value;
  if (DBusProperties::GetUint32(
      properties,
      MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE,
      &uint_value)) {
    state_1x = static_cast<MMModemCdmaRegistrationState>(uint_value);
    registration_changed = true;
  }
  if (DBusProperties::GetUint32(
      properties,
      MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE,
      &uint_value)) {
    state_evdo = static_cast<MMModemCdmaRegistrationState>(uint_value);
    registration_changed = true;
  }
  if (DBusProperties::GetUint32(
      properties,
      MM_MODEM_MODEMCDMA_PROPERTY_SID,
      &uint_value)) {
    sid = uint_value;
    registration_changed = true;
  }
  if (DBusProperties::GetUint32(
      properties,
      MM_MODEM_MODEMCDMA_PROPERTY_NID,
      &uint_value)) {
    nid = uint_value;
    registration_changed = true;
  }
  if (DBusProperties::GetUint32(
      properties,
      MM_MODEM_MODEMCDMA_PROPERTY_ACTIVATIONSTATE,
      &uint_value)) {
    activation_state_ = static_cast<MMModemCdmaActivationState>(uint_value);
    HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
  }
  if (registration_changed)
    OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid);
}

void CellularCapabilityUniversalCDMA::OnCDMARegistrationChanged(
      MMModemCdmaRegistrationState state_1x,
      MMModemCdmaRegistrationState state_evdo,
      uint32_t sid, uint32_t nid) {
  SLOG(Cellular, 2) << __func__
                    << ": state_1x=" << state_1x
                    << ", state_evdo=" << state_evdo;
  cdma_1x_registration_state_ = state_1x;
  cdma_evdo_registration_state_ = state_evdo;
  sid_ = sid;
  nid_ = nid;
  UpdateOperatorInfo();
  cellular()->HandleNewRegistrationState();
}

}  // namespace shill
