// 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_DEVICE_H_
#define SHILL_DEVICE_H_

#include <string>
#include <vector>

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

#include "shill/adaptor_interfaces.h"
#include "shill/callbacks.h"
#include "shill/connection_health_checker.h"
#include "shill/event_dispatcher.h"
#include "shill/ip_address.h"
#include "shill/ipconfig.h"
#include "shill/portal_detector.h"
#include "shill/property_store.h"
#include "shill/refptr_types.h"
#include "shill/service.h"
#include "shill/technology.h"

namespace shill {

class ControlInterface;
class DHCPProvider;
class DeviceAdaptorInterface;
class Endpoint;
class Error;
class EventDispatcher;
class GeolocationInfo;
class LinkMonitor;
class Manager;
class Metrics;
class RTNLHandler;
class TrafficMonitor;

// Device superclass.  Individual network interfaces types will inherit from
// this class.
class Device : public base::RefCounted<Device> {
 public:
  // Progressively scanning for access points (APs) is done with multiple scans,
  // each containing a group of channels.  The scans are performed in order of
  // decreasing likelihood of connecting on one of the channels in a group
  // (the number of channels in a group is a matter for system tuning).  Fully
  // scanning for APs does a complete scan of all the channels in a single scan.
  // Progressive scanning is supported for wifi devices; technologies that
  // support scan but don't support progressive scan will always perform a full
  // scan, regardless of the requested scan type.
  enum ScanType { kProgressiveScan, kFullScan };

  // A constructor for the Device object
  Device(ControlInterface *control_interface,
         EventDispatcher *dispatcher,
         Metrics *metrics,
         Manager *manager,
         const std::string &link_name,
         const std::string &address,
         int interface_index,
         Technology::Identifier technology);

  // Enable or disable the device.
  virtual void SetEnabled(bool enable);
  // Enable or disable the device, and save the setting in the profile.
  // The setting is persisted before the enable or disable operation
  // starts, so that even if it fails, the user's intent is still recorded
  // for the next time shill restarts.
  virtual void SetEnabledPersistent(bool enable,
                                    Error *error,
                                    const ResultCallback &callback);

  // Returns true if the underlying device reports that it is already enabled.
  // Used when the device is registered with the Manager, so that shill can
  // sync its state/ with the true state of the device. The default is to
  // report false.
  virtual bool IsUnderlyingDeviceEnabled() const;

  virtual void LinkEvent(unsigned flags, unsigned change);

  // The default implementation sets |error| to kNotSupported.
  virtual void Scan(ScanType scan_type, Error *error);
  virtual void RegisterOnNetwork(const std::string &network_id, Error *error,
                                 const ResultCallback &callback);
  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);
  virtual void Reset(Error *error, const ResultCallback &callback);

  virtual void SetCarrier(const std::string &carrier,
                          Error *error, const ResultCallback &callback);
  virtual void DisableIPv6();
  virtual void EnableIPv6();
  virtual void EnableIPv6Privacy();

  // Request the removal of reverse-path filtering for this interface.
  // This will allow packets destined for this interface to be accepted,
  // even if this is not the default route for such a packet to arrive.
  virtual void DisableReversePathFilter();

  // Request reverse-path filtering for this interface.
  virtual void EnableReversePathFilter();

  // Returns true if the selected service on the device (if any) is connected.
  // Returns false if there is no selected service, or if the selected service
  // is not connected.
  bool IsConnected() const;

  // Called by Device so that subclasses can run hooks on the selected service
  // getting an IP.  Subclasses should call up to the parent first.
  virtual void OnConnected();

  // Called by the Connection so that the Device can update the service sorting
  // after one connection is bound to another.
  virtual void OnConnectionUpdated();

  // Returns true if the selected service on the device (if any) is connected
  // and matches the passed-in argument |service|.  Returns false if there is
  // no connected service, or if it does not match |service|.
  virtual bool IsConnectedToService(const ServiceRefPtr &service) const;

  // Restart the portal detection process on a connected device.  This is
  // useful if the properties on the connected service have changed in a
  // way that may affect the decision to run portal detection at all.
  // Returns true if portal detection was started.
  virtual bool RestartPortalDetection();

  // Get receive and transmit byte counters.
  virtual uint64 GetReceiveByteCount();
  virtual uint64 GetTransmitByteCount();

  // Reset the persisted byte counters associated with the device.
  void ResetByteCounters();

  // Requests that portal detection be done, if this device has the default
  // connection.  Returns true if portal detection was started.
  virtual bool RequestPortalDetection();

  std::string GetRpcIdentifier() const;
  std::string GetStorageIdentifier();

  // Returns a list of Geolocation objects. Each object is multiple
  // key-value pairs representing one entity that can be used for
  // Geolocation.
  virtual std::vector<GeolocationInfo> GetGeolocationObjects() const;

  const std::string &address() const { return hardware_address_; }
  const std::string &link_name() const { return link_name_; }
  int interface_index() const { return interface_index_; }
  const ConnectionRefPtr &connection() const { return connection_; }
  bool enabled() const { return enabled_; }
  bool enabled_persistent() const { return enabled_persistent_; }
  virtual Technology::Identifier technology() const { return technology_; }
  std::string GetTechnologyString(Error *error);

  virtual const IPConfigRefPtr &ipconfig() const { return ipconfig_; }
  void set_ipconfig(const IPConfigRefPtr &config) { ipconfig_ = config; }

  const std::string &FriendlyName() const;

  // Returns a string that is guaranteed to uniquely identify this Device
  // instance.
  const std::string &UniqueName() const;

  PropertyStore *mutable_store() { return &store_; }
  const PropertyStore &store() const { return store_; }
  RTNLHandler *rtnl_handler() { return rtnl_handler_; }
  bool running() const { return running_; }

  EventDispatcher *dispatcher() const { return dispatcher_; }

  // Load configuration for the device from |storage|.  This may include
  // instantiating non-visible services for which configuration has been
  // stored.
  virtual bool Load(StoreInterface *storage);

  // Save configuration for the device to |storage|.
  virtual bool Save(StoreInterface *storage);

  void set_dhcp_provider(DHCPProvider *provider) { dhcp_provider_ = provider; }

  DeviceAdaptorInterface *adaptor() const { return adaptor_.get(); }

  void set_health_checker(ConnectionHealthChecker *health_checker) {
    health_checker_.reset(health_checker);
  }

  // Suspend event handler. Called by Manager before the system
  // suspends. For this callback to be useful, the device must specify
  // a suspend delay. Otherwise, there is no guarantee that the device
  // will have time to complete its suspend actions, before the system
  // is suspended.
  //
  // TODO(quiche): Add support for suspend delays. crbug.com/215582
  virtual void OnBeforeSuspend();

  // Resume event handler. Called by Manager as the system resumes.
  // The base class implementation takes care of renewing a DHCP lease
  // (if necessary). Derived classes may implement any technology
  // specific requirements by overriding, but should include a call to
  // the base class implementation.
  virtual void OnAfterResume();

  // Destroy the lease, if any, with this |name|.
  // Called by the service during Unload() as part of the cleanup sequence.
  virtual void DestroyIPConfigLease(const std::string &name);

 protected:
  friend class base::RefCounted<Device>;
  friend class DeviceHealthCheckerTest;
  FRIEND_TEST(CellularServiceTest, IsAutoConnectable);
  FRIEND_TEST(CellularTest, EnableTrafficMonitor);
  FRIEND_TEST(CellularTest, ModemStateChangeDisable);
  FRIEND_TEST(CellularTest, UseNoArpGateway);
  FRIEND_TEST(ConnectionTest, OnRouteQueryResponse);
  FRIEND_TEST(DeviceHealthCheckerTest, HealthCheckerPersistsAcrossDeviceReset);
  FRIEND_TEST(DeviceHealthCheckerTest, RequestConnectionHealthCheck);
  FRIEND_TEST(DeviceHealthCheckerTest, SetupHealthChecker);
  FRIEND_TEST(DeviceTest, AcquireIPConfig);
  FRIEND_TEST(DeviceTest, DestroyIPConfig);
  FRIEND_TEST(DeviceTest, DestroyIPConfigNULL);
  FRIEND_TEST(DeviceTest, GetProperties);
  FRIEND_TEST(DeviceTest, Load);
  FRIEND_TEST(DeviceTest, Save);
  FRIEND_TEST(DeviceTest, SelectedService);
  FRIEND_TEST(DeviceTest, SetEnabledPersistent);
  FRIEND_TEST(DeviceTest, SetServiceConnectedState);
  FRIEND_TEST(DeviceTest, Start);
  FRIEND_TEST(DeviceTest, StartTrafficMonitor);
  FRIEND_TEST(DeviceTest, Stop);
  FRIEND_TEST(DeviceTest, StopTrafficMonitor);
  FRIEND_TEST(ManagerTest, DeviceRegistrationAndStart);
  FRIEND_TEST(ManagerTest, ConnectedTechnologies);
  FRIEND_TEST(ManagerTest, DefaultTechnology);
  FRIEND_TEST(ManagerTest, SetEnabledStateForTechnology);
  FRIEND_TEST(WiFiMainTest, Connect);
  FRIEND_TEST(WiFiMainTest, UseArpGateway);
  FRIEND_TEST(WiMaxTest, ConnectTimeout);
  FRIEND_TEST(WiMaxTest, UseNoArpGateway);

  virtual ~Device();

  // Each device must implement this method to do the work needed to
  // enable the device to operate for establishing network connections.
  // The |error| argument, if not NULL,
  // will refer to an Error that starts out with the value
  // Error::kOperationInitiated. This reflects the assumption that
  // enable (and disable) operations will usually be non-blocking,
  // and their completion will be indicated by means of an asynchronous
  // reply sometime later. There are two circumstances in which a
  // device's Start() method may overwrite |error|:
  //
  // 1. If an early failure is detected, such that the non-blocking
  //    part of the operation never takes place, then |error| should
  //    be set to the appropriate value corresponding to the type
  //    of failure. This is the "immediate failure" case.
  // 2. If the device is enabled without performing any non-blocking
  //    steps, then |error| should be Reset, i.e., its value set
  //    to Error::kSuccess. This is the "immediate success" case.
  //
  // In these two cases, because completion is immediate, |callback|
  // is not used. If neither of these two conditions holds, then |error|
  // should not be modified, and |callback| should be passed to the
  // method that will initiate the non-blocking operation.
  virtual void Start(Error *error,
                     const EnabledStateChangedCallback &callback) = 0;

  // Each device must implement this method to do the work needed to
  // disable the device, i.e., clear any running state, and make the
  // device no longer capable of establishing network connections.
  // The discussion for Start() regarding the use of |error| and
  // |callback| apply to Stop() as well.
  virtual void Stop(Error *error,
                    const EnabledStateChangedCallback &callback) = 0;

  // The EnabledStateChangedCallback that gets passed to the device's
  // Start() and Stop() methods is bound to this method. |callback|
  // is the callback that was passed to SetEnabled().
  void OnEnabledStateChanged(const ResultCallback &callback,
                             const Error &error);

  // Drops the currently selected service along with its IP configuration and
  // connection, if any.
  virtual void DropConnection();

  // If there's an IP configuration in |ipconfig_|, releases the IP address and
  // destroys the configuration instance.
  void DestroyIPConfig();

  // Creates a new DHCP IP configuration instance, stores it in |ipconfig_| and
  // requests a new IP configuration.  Saves the DHCP lease to the generic
  // lease filename based on the interface name.  Registers a callback to
  // IPConfigUpdatedCallback on IP configuration changes. Returns true if the IP
  // request was successfully sent.
  bool AcquireIPConfig();

  // Creates a new DHCP IP configuration instance, stores it in |ipconfig_| and
  // requests a new IP configuration.  Saves the DHCP lease to a filename
  // based on the passed-in |lease_name|.  Registers a callback to
  // IPConfigUpdatedCallback on IP configuration changes. Returns true if the IP
  // request was successfully sent.
  bool AcquireIPConfigWithLeaseName(const std::string &lease_name);

  // Callback invoked on every IP configuration update.
  void OnIPConfigUpdated(const IPConfigRefPtr &ipconfig, bool success);

  // Called by Device so that subclasses can run hooks on the selected service
  // failing to get an IP.  The default implementation disconnects the selected
  // service with Service::kFailureDHCP.
  virtual void OnIPConfigFailure();

  // Maintain connection state (Routes, IP Addresses and DNS) in the OS.
  void CreateConnection();

  // Remove connection state
  void DestroyConnection();

  // Selects a service to be "current" -- i.e. link-state or configuration
  // events that happen to the device are attributed to this service.
  void SelectService(const ServiceRefPtr &service);

  // Set the state of the selected service
  virtual void SetServiceState(Service::ConnectState state);

  // Set the failure of the selected service (implicitly sets the state to
  // "failure")
  virtual void SetServiceFailure(Service::ConnectFailure failure_state);

  // Records the failure mode and time of the selected service, and
  // sets the Service state of the selected service to "Idle".
  // Avoids showing a failure mole in the UI.
  virtual void SetServiceFailureSilent(Service::ConnectFailure failure_state);

  virtual void SetupConnectionHealthChecker();

  // Checks the network connectivity status by creating a TCP connection, and
  // optionally sending a small amout of data.
  void RequestConnectionHealthCheck();

  // Responds to the result from connection health checker in a device specific
  // manner.
  virtual void OnConnectionHealthCheckerResult(
      ConnectionHealthChecker::Result result);

  // Called by the Portal Detector whenever a trial completes.  Device
  // subclasses that choose unique mappings from portal results to connected
  // states can override this method in order to do so.
  virtual void PortalDetectorCallback(const PortalDetector::Result &result);

  // Initiate portal detection, if enabled for this device type.
  bool StartPortalDetection();

  // Stop portal detection if it is running.
  void StopPortalDetection();

  // Initiate link monitoring, if enabled for this device type.
  bool StartLinkMonitor();

  // Stop link monitoring if it is running.
  void StopLinkMonitor();

  // Respond to a LinkMonitor failure in a Device-specific manner.
  virtual void OnLinkMonitorFailure();

  // Initiates traffic monitoring if it's enabled via
  // set_traffic_monitor_enabled() and returns true if the monitoring
  // is started.
  bool StartTrafficMonitor();

  // Stops traffic monitoring if it is running.
  void StopTrafficMonitor();

  // Responds to a TrafficMonitor no-network-routing failure in a
  // Device-specific manner.
  virtual void OnNoNetworkRouting();

  // Set the state of the selected service, with checks to make sure
  // the service is already in a connected state before doing so.
  void SetServiceConnectedState(Service::ConnectState state);

  // Specifies whether an ARP gateway should be used for the
  // device technology.
  virtual bool ShouldUseArpGateway() const;

  const ServiceRefPtr &selected_service() const { return selected_service_; }

  void HelpRegisterConstDerivedString(
      const std::string &name,
      std::string(Device::*get)(Error *));

  void HelpRegisterConstDerivedRpcIdentifiers(
      const std::string &name,
      RpcIdentifiers(Device::*get)(Error *));

  void HelpRegisterConstDerivedUint64(
      const std::string &name,
      uint64(Device::*get)(Error *));

  // Property getters reserved for subclasses
  ControlInterface *control_interface() const { return control_interface_; }
  Metrics *metrics() const { return metrics_; }
  Manager *manager() const { return manager_; }
  const LinkMonitor *link_monitor() const { return link_monitor_.get(); }
  void set_link_monitor(LinkMonitor *link_monitor);
  const TrafficMonitor *traffic_monitor() const {
    return traffic_monitor_.get();
  }

  // Ownership of |traffic_monitor| is taken.
  void set_traffic_monitor(TrafficMonitor *traffic_monitor);
  bool traffic_monitor_enabled() const { return traffic_monitor_enabled_; }
  void set_traffic_monitor_enabled(bool traffic_monitor_enabled) {
    traffic_monitor_enabled_ = traffic_monitor_enabled;
  }

 private:
  friend class CellularCapabilityTest;
  friend class CellularTest;
  friend class DeviceAdaptorInterface;
  friend class DeviceByteCountTest;
  friend class DevicePortalDetectionTest;
  friend class DeviceTest;
  friend class EthernetTest;
  friend class OpenVPNDriverTest;
  friend class WiFiObjectTest;

  static const char kIPFlagTemplate[];
  static const char kIPFlagVersion4[];
  static const char kIPFlagVersion6[];
  static const char kIPFlagDisableIPv6[];
  static const char kIPFlagUseTempAddr[];
  static const char kIPFlagUseTempAddrUsedAndDefault[];
  static const char kIPFlagReversePathFilter[];
  static const char kIPFlagReversePathFilterEnabled[];
  static const char kIPFlagReversePathFilterLooseMode[];
  static const char kStorageIPConfigs[];
  static const char kStoragePowered[];
  static const char kStorageReceiveByteCount[];
  static const char kStorageTransmitByteCount[];

  // Configure static IP address parameters if the service provides them.
  void ConfigureStaticIPTask();

  void SetEnabledInternal(bool enable, bool persist,
                          Error *error, const ResultCallback &callback);

  // Right now, Devices reference IPConfigs directly when persisted to disk
  // It's not clear that this makes sense long-term, but that's how it is now.
  // This call generates a string in the right format for this persisting.
  // |suffix| is injected into the storage identifier used for the configs.
  std::string SerializeIPConfigs(const std::string &suffix);

  // Set an IP configuration flag on the device.  |ip_version| should be
  // "ipv6" or "ipv4".  |flag| should be the name of the flag to be set
  // and |value| is what this flag should be set to.
  bool SetIPFlag(IPAddress::Family family, const std::string &flag,
                 const std::string &value);

  std::vector<std::string> AvailableIPConfigs(Error *error);
  std::string GetRpcConnectionIdentifier();

  // Get the LinkMonitor's average response time.
  uint64 GetLinkMonitorResponseTime(Error *error);

  // Get receive and transmit byte counters. These methods simply wrap
  // GetReceiveByteCount and GetTransmitByteCount in order to be used by
  // HelpRegisterConstDerivedUint64.
  uint64 GetReceiveByteCountProperty(Error *error);
  uint64 GetTransmitByteCountProperty(Error *error);

  // |enabled_persistent_| is the value of the Powered property, as
  // read from the profile. If it is not found in the profile, it
  // defaults to true. |enabled_| reflects the real-time state of
  // the device, i.e., enabled or disabled. |enabled_pending_| reflects
  // the target state of the device while an enable or disable operation
  // is occurring.
  //
  // Some typical sequences for these state variables are shown below.
  //
  // Shill starts up, profile has been read:
  //  |enabled_persistent_|=true   |enabled_|=false   |enabled_pending_|=false
  //
  // Shill acts on the value of |enabled_persistent_|, calls SetEnabled(true):
  //  |enabled_persistent_|=true   |enabled_|=false   |enabled_pending_|=true
  //
  // SetEnabled completes successfully, device is enabled:
  //  |enabled_persistent_|=true   |enabled_|=true    |enabled_pending_|=true
  //
  // User presses "Disable" button, SetEnabled(false) is called:
  //  |enabled_persistent_|=false   |enabled_|=true    |enabled_pending_|=false
  //
  // SetEnabled completes successfully, device is disabled:
  //  |enabled_persistent_|=false   |enabled_|=false    |enabled_pending_|=false
  bool enabled_;
  bool enabled_persistent_;
  bool enabled_pending_;

  // Other properties
  bool reconnect_;
  const std::string hardware_address_;

  PropertyStore store_;

  const int interface_index_;
  bool running_;  // indicates whether the device is actually in operation
  const std::string link_name_;
  const std::string unique_id_;
  ControlInterface *control_interface_;
  EventDispatcher *dispatcher_;
  Metrics *metrics_;
  Manager *manager_;
  IPConfigRefPtr ipconfig_;
  ConnectionRefPtr connection_;
  base::WeakPtrFactory<Device> weak_ptr_factory_;
  scoped_ptr<DeviceAdaptorInterface> adaptor_;
  scoped_ptr<PortalDetector> portal_detector_;
  scoped_ptr<LinkMonitor> link_monitor_;
  scoped_ptr<TrafficMonitor> traffic_monitor_;
  scoped_ptr<ConnectionHealthChecker> health_checker_;
  bool traffic_monitor_enabled_;
  base::Callback<void(const PortalDetector::Result &)>
      portal_detector_callback_;
  Technology::Identifier technology_;
  // The number of portal detection attempts from Connected to Online state.
  // This includes all failure/timeout attempts and the final successful
  // attempt.
  int portal_attempts_to_online_;

  // Keep track of the offset between the interface-reported byte counters
  // and our persisted value.
  uint64 receive_byte_offset_;
  uint64 transmit_byte_offset_;

  // Maintain a reference to the connected / connecting service
  ServiceRefPtr selected_service_;

  // Cache singleton pointers for performance and test purposes.
  DHCPProvider *dhcp_provider_;
  RTNLHandler *rtnl_handler_;

  DISALLOW_COPY_AND_ASSIGN(Device);
};

}  // namespace shill

#endif  // SHILL_DEVICE_H_
