// Copyright 2018 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_CELLULAR_CAPABILITY_H_
#define SHILL_CELLULAR_CELLULAR_CAPABILITY_H_

#include <memory>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/macros.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/callbacks.h"
#include "shill/cellular/cellular.h"
#include "shill/metrics.h"

namespace shill {

class Cellular;
class CellularBearer;
class Error;
class ModemInfo;

// Cellular devices instantiate subclasses of CellularCapability that
// handle the specific modem technologies and capabilities.
//
// The CellularCapability is directly subclassed by:
// *  CelllularCapabilityUniversal which handles all modems managed by
//    a modem manager using the the org.chromium.ModemManager1 DBUS
//    interface.
// *  CellularCapabilityClassic which handles all modems managed by a
//    modem manager using the older org.chromium.ModemManager DBUS
//    interface.  This class is further subclassed to represent CDMA
//    and GSM modems.
//
// Pictorially:
//
// CellularCapability
//       |
//       |-- CellularCapabilityUniversal
//       |            |
//       |            |-- CellularCapabilityUniversalCdma
//       |
//       |-- CellularCapabilityClassic
//                    |
//                    |-- CellularCapabilityGsm
//                    |
//                    |-- CellularCapabilityCdma
//
// TODO(armansito): Currently, 3GPP logic is handled by
// CellularCapabilityUniversal. Eventually CellularCapabilityUniversal will
// only serve as the abstract base class for ModemManager1 3GPP and CDMA
// capabilities.
class CellularCapability {
 public:
  static const int kTimeoutActivate;
  static const int kTimeoutConnect;
  static const int kTimeoutDefault;
  static const int kTimeoutDisconnect;
  static const int kTimeoutEnable;
  static const int kTimeoutGetLocation;
  static const int kTimeoutRegister;
  static const int kTimeoutReset;
  static const int kTimeoutScan;
  static const int kTimeoutSetupLocation;

  static const char kModemPropertyIMSI[];

  static std::unique_ptr<CellularCapability> Create(Cellular::Type type,
                                                    Cellular* cellular,
                                                    ModemInfo* modem_info);

  virtual ~CellularCapability();

  virtual std::string GetTypeString() const = 0;

  // Called when the modem manager has sent a property change notification
  // signal.
  virtual void OnPropertiesChanged(
      const std::string& interface,
      const KeyValueStore& changed_properties,
      const std::vector<std::string>& invalidated_properties) = 0;

  // -------------------------------------------------------------------------
  // Modem management
  // -------------------------------------------------------------------------

  // StartModem attempts to put the modem in a state in which it is usable for
  // creating services and establishing connections (if network conditions
  // permit). It potentially consists of multiple non-blocking calls to the
  // modem-manager server. After each call, control is passed back up to the
  // main loop. Each time a reply to a non-blocking call is received, the
  // operation advances to the next step, until either an error occurs in one of
  // them, or all the steps have been completed, at which point StartModem() is
  // finished.
  virtual void StartModem(Error* error, const ResultCallback& callback) = 0;

  // StopModem disconnects and disables a modem asynchronously.  |callback| is
  // invoked when this completes and the result is passed to the callback.
  virtual void StopModem(Error* error, const ResultCallback& callback) = 0;

  // Resets the modem.
  //
  // The default implementation fails by returning kNotSupported via |error|.
  virtual void Reset(Error* error, const ResultCallback& callback);

  // Checks to see if all proxies have been initialized.
  virtual bool AreProxiesInitialized() const = 0;

  // -------------------------------------------------------------------------
  // Activation
  // -------------------------------------------------------------------------

  // Returns true if service activation is required.
  //
  // The default implementation returns false.
  virtual bool IsServiceActivationRequired() const;

  // Returns true if the modem is being activated.
  //
  // The default implementation returns false.
  virtual bool IsActivating() const;

  // Activates the modem.
  //
  // The default implementation fails by returning kNotSupported via |error|.
  virtual void Activate(const std::string& carrier,
                        Error* error, const ResultCallback& callback);

  // Initiates the necessary to steps to verify that the cellular service has
  // been activated. Once these steps have been completed, the service should
  // be marked as activated.
  //
  // The default implementation fails by returning kNotSupported via |error|.
  virtual void CompleteActivation(Error* error);

  // -------------------------------------------------------------------------
  // Network service and registration
  // -------------------------------------------------------------------------

  // Configures the modem to support the |carrier|.
  //
  // The default implementation fails by returning kNotSupported via |error|.
  virtual void SetCarrier(const std::string& carrier,
                          Error* error,
                          const ResultCallback& callback);

  // Asks the modem to scan for networks.
  //
  // The default implementation fails by returning kNotSupported via |error|.
  //
  // Subclasses should implement this by fetching scan results asynchronously.
  // When the results are ready, update the kFoundNetworksProperty and send a
  // property change notification.  Finally, callback must be invoked to inform
  // the caller that the scan has completed.
  //
  // Errors are not generally reported, but on error the kFoundNetworksProperty
  // should be cleared and a property change notification sent out.
  //
  // TODO(jglasgow): Refactor to reuse code by putting notification logic into
  // Cellular or CellularCapability.
  //
  // TODO(jglasgow): Implement real error handling.
  virtual void Scan(Error* error, const ResultStringmapsCallback& callback);

  // Registers on a network with |network_id|.
  virtual void RegisterOnNetwork(const std::string& network_id,
                                 Error* error,
                                 const ResultCallback& callback);

  // Returns true if the modem is registered on a network, which can be a home
  // or roaming network. It is possible that we cannot determine whether it is
  // a home or roaming network, but we still consider the modem is registered.
  virtual bool IsRegistered() const = 0;

  // If we are informed by means of something other than a signal indicating
  // a registration state change that the modem has unregistered from the
  // network, we need to update the network-type-specific capability object.
  virtual void SetUnregistered(bool searching) = 0;

  // Invoked by the parent Cellular device when a new service is created.
  virtual void OnServiceCreated() = 0;

  // Hook called by the Cellular device when either the Home Provider or the
  // Serving Operator changes. Default implementation calls other hooks declared
  // below. Overrides should chain up to this function.
  // Note: This may be called before |CellularService| is created.
  virtual void OnOperatorChanged();
  virtual void UpdateServiceOLP();

  // Returns an empty string if the network technology is unknown.
  virtual std::string GetNetworkTechnologyString() const = 0;

  virtual std::string GetRoamingStateString() const = 0;

  // TODO(armansito): Remove this method once cromo is deprecated.
  virtual void GetSignalQuality() = 0;

  // -------------------------------------------------------------------------
  // Location reporting
  // -------------------------------------------------------------------------
  // These default to dummy methods, and should be overriden in subclasses if
  // the modem supports location reporting
  virtual void SetupLocation(uint32_t sources,
                             bool signal_location,
                             const ResultCallback& callback);

  virtual void GetLocation(const StringCallback& callback);

  virtual bool IsLocationUpdateSupported();

  // -------------------------------------------------------------------------
  // Connection management
  // -------------------------------------------------------------------------

  // Fills |properties| with properties for establishing a connection, which
  // will be passed to Connect().
  virtual void SetupConnectProperties(KeyValueStore* properties) = 0;

  // Connects the modem to a network based on the connection properties
  // specified by |properties|.
  virtual void Connect(const KeyValueStore& properties,
                       Error* error,
                       const ResultCallback& callback) = 0;

  // Disconnects the modem from a network.
  virtual void Disconnect(Error* error, const ResultCallback& callback) = 0;

  // Called when a disconnect operation completes, successful or not.
  //
  // The default implementation does nothing.
  virtual void DisconnectCleanup();

  // Returns a pointer to the current active bearer object or nullptr if no
  // active bearer exists. The returned bearer object is managed by this
  // capability object. This implementation returns nullptr by default.
  virtual CellularBearer* GetActiveBearer() const;

  // -------------------------------------------------------------------------
  // SIM PIN management
  // -------------------------------------------------------------------------

  // The default implementation fails by returning kNotSupported via |error|.
  virtual void RequirePIN(const std::string& pin,
                          bool require,
                          Error* error,
                          const ResultCallback& callback);

  virtual void EnterPIN(const std::string& pin,
                        Error* error,
                        const ResultCallback& callback);

  virtual void UnblockPIN(const std::string& unblock_code,
                          const std::string& pin,
                          Error* error,
                          const ResultCallback& callback);

  virtual void ChangePIN(const std::string& old_pin,
                         const std::string& new_pin,
                         Error* error,
                         const ResultCallback& callback);

  // -------------------------------------------------------------------------

  Cellular* cellular() const { return cellular_; }
  ControlInterface* control_interface() const {
    return modem_info_->control_interface();
  }
  ModemInfo* modem_info() const { return modem_info_; }

 protected:
  // |cellular| is the parent Cellular device.
  CellularCapability(Cellular* cellular,
                     ModemInfo* modem_info);

  // Releases all proxies held by the object. This is most useful during unit
  // tests.
  virtual void ReleaseProxies() = 0;

  static void OnUnsupportedOperation(const char* operation, Error* error);

 private:
  friend class CellularCapabilityGsmTest;
  friend class CellularCapabilityClassicTest;
  friend class CellularCapabilityUniversalTest;
  friend class CellularCapabilityUniversalCdmaTest;
  friend class CellularTest;
  FRIEND_TEST(CellularCapabilityUniversalMainTest, UpdateActiveBearer);
  FRIEND_TEST(CellularTest, Connect);

  Cellular* cellular_;
  ModemInfo* modem_info_;

  DISALLOW_COPY_AND_ASSIGN(CellularCapability);
};

}  // namespace shill

#endif  // SHILL_CELLULAR_CELLULAR_CAPABILITY_H_
