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

#ifndef SHILL_CELLULAR_CAPABILITY_CDMA_
#define SHILL_CELLULAR_CAPABILITY_CDMA_

#include <base/memory/scoped_ptr.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/cellular_capability.h"
#include "shill/cellular_service.h"
#include "shill/modem_cdma_proxy_interface.h"

namespace shill {

class CellularCapabilityCDMA : public CellularCapability {
 public:
  CellularCapabilityCDMA(Cellular *cellular, ProxyFactory *proxy_factory);

  // Inherited from CellularCapability.
  virtual void StartModem(Error *error, const ResultCallback &callback);
  virtual void OnServiceCreated();
  virtual void UpdateStatus(const DBusPropertiesMap &properties);
  virtual void SetupConnectProperties(DBusPropertiesMap *properties);
  virtual void Activate(const std::string &carrier, Error *error,
                        const ResultCallback &callback);
  virtual bool IsRegistered();
  virtual std::string CreateFriendlyServiceName();
  virtual std::string GetNetworkTechnologyString() const;
  virtual std::string GetRoamingStateString() const;
  virtual std::string GetTypeString() const { return "CDMA"; }
  virtual void GetSignalQuality();
  virtual void GetRegistrationState();
  virtual void GetProperties(const ResultCallback &callback);
  virtual void OnModemManagerPropertiesChanged(
      const DBusPropertiesMap &properties);

  virtual void GetMEID(const ResultCallback &callback);

  uint32 activation_state() const { return activation_state_; }
  uint32 registration_state_evdo() const { return registration_state_evdo_; }
  uint32 registration_state_1x() const { return registration_state_1x_; }

 protected:
  virtual void InitProxies();
  virtual void ReleaseProxies();

 private:
  friend class CellularCapabilityCDMATest;
  friend class CellularTest;
  FRIEND_TEST(CellularCapabilityCDMATest, Activate);
  FRIEND_TEST(CellularCapabilityCDMATest, ActivateError);
  FRIEND_TEST(CellularCapabilityCDMATest, CreateFriendlyServiceName);
  FRIEND_TEST(CellularCapabilityCDMATest, GetActivationStateString);
  FRIEND_TEST(CellularCapabilityCDMATest, GetActivationErrorString);
  FRIEND_TEST(CellularTest, CreateService);

  static const char kPhoneNumber[];

  void HandleNewActivationState(uint32 error);

  // Updates the serving operator on the active service.
  void UpdateServingOperator();

  static std::string GetActivationStateString(uint32 state);
  static std::string GetActivationErrorString(uint32 error);

  // Signal callbacks from the Modem.CDMA interface
  virtual void OnActivationStateChangedSignal(
      uint32 activation_state,
      uint32 activation_error,
      const DBusPropertiesMap &status_changes);
  virtual void OnRegistrationStateChangedSignal(
      uint32 state_1x, uint32 state_evdo);
  virtual void OnSignalQualitySignal(uint32 strength);

  // Method reply callbacks from the Modem.CDMA interface
  virtual void OnActivateReply(const ResultCallback &callback,
                               uint32 status, const Error &error);

  virtual void OnGetRegistrationStateReply(uint32 state_1x, uint32 state_evdo,
                                           const Error &error);
  virtual void OnGetSignalQualityReply(uint32 strength,
                                       const Error &error);

  scoped_ptr<ModemCDMAProxyInterface> proxy_;
  base::WeakPtrFactory<CellularCapabilityCDMA> weak_ptr_factory_;

  uint32 activation_state_;
  uint32 registration_state_evdo_;
  uint32 registration_state_1x_;
  uint16 prl_version_;
  CellularService::OLP olp_;
  std::string usage_url_;

  static unsigned int friendly_service_name_id_;

  DISALLOW_COPY_AND_ASSIGN(CellularCapabilityCDMA);
};

}  // namespace shill

#endif  // SHILL_CELLULAR_CAPABILITY_CDMA_
