// Copyright 2018 The ChromiumOS Authors
// 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 <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <base/time/time.h>
#include <chromeos/patchpanel/dbus/client.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <net-base/ip_address.h>
#include <net-base/mac_address.h>
#include <net-base/rtnl_handler.h>

#include "shill/adaptor_interfaces.h"
#include "shill/callbacks.h"
#include "shill/event_dispatcher.h"
#include "shill/geolocation_info.h"
#include "shill/metrics.h"
#include "shill/network/connection_diagnostics.h"
#include "shill/network/legacy_dhcp_controller.h"
#include "shill/network/network.h"
#include "shill/network/portal_detector.h"
#include "shill/refptr_types.h"
#include "shill/service.h"
#include "shill/store/property_store.h"
#include "shill/technology.h"

namespace shill {

class ControlInterface;
class DHCPProvider;
class DeviceAdaptorInterface;
class Error;
class EventDispatcher;
class Manager;

// Device superclass.  Individual network interfaces types will inherit from
// this class.
class Device : public base::RefCounted<Device>, public Network::EventHandler {
 public:
  // A constructor for the Device object
  Device(Manager* manager,
         const std::string& link_name,
         std::optional<net_base::MacAddress> mac_address,
         int interface_index,
         Technology technology,
         bool fixed_ip_params = false,
         bool use_implicit_network = true);
  Device(const Device&) = delete;
  Device& operator=(const Device&) = delete;

  // Initialize type-specific network interface properties.
  virtual void Initialize();
  virtual void OnDeregistered();

  // Enable or disable the device. This is a convenience method for
  // cases where we want to SetEnabledNonPersistent, but don't care
  // about the results.
  mockable void SetEnabled(bool enable);
  // Enable or disable the device. Unlike SetEnabledPersistent, it does not
  // save the setting in the profile.
  //
  // TODO(quiche): Replace both of the next two methods with calls to
  // SetEnabledChecked.
  void SetEnabledNonPersistent(bool enable, ResultCallback callback);
  // 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.
  void SetEnabledPersistent(bool enable, ResultCallback callback);
  // Enable or disable the Device, depending on |enable|.
  // Save the new setting to the profile, if |persist| is true.
  // Report synchronous errors using |error|, and asynchronous completion
  // with |callback|.
  mockable void SetEnabledChecked(bool enable,
                                  bool persist,
                                  ResultCallback callback);
  // Similar to SetEnabledChecked, but without coherence checking, and
  // without saving the new value of |enable| to the profile. If you
  // are rational (i.e. not Cellular), you should use
  // SetEnabledChecked instead.
  mockable void SetEnabledUnchecked(bool enable, 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(Error* error, const std::string& reason, bool is_dbus_call);
  virtual void RegisterOnNetwork(const std::string& network_id,
                                 ResultCallback callback);
  virtual void RequirePin(const std::string& pin,
                          bool require,
                          ResultCallback callback);
  virtual void EnterPin(const std::string& pin, ResultCallback callback);
  virtual void UnblockPin(const std::string& unblock_code,
                          const std::string& pin,
                          ResultCallback callback);
  virtual void ChangePin(const std::string& old_pin,
                         const std::string& new_pin,
                         ResultCallback callback);
  virtual void Reset(ResultCallback callback);

  // 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 Device so that subclasses can run hooks on the selected service
  // changed. This function is called after the |selected_service_| changed so
  // the subclasses can call the getter to retrieve the new selected service.
  // Note that the base class does nothing here so the subclasses don't need to
  // call up to the parent.
  virtual void OnSelectedServiceChanged(const ServiceRefPtr& old_service);

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

  // Update the Geolocation objects. Each object is multiple
  // key-value pairs representing one entity that can be used for
  // Geolocation.
  virtual void UpdateGeolocationObjects(
      std::vector<GeolocationInfo>* geolocation_infos) const;

  std::optional<net_base::MacAddress> mac_address() const {
    return mac_address_;
  }
  const std::string& link_name() const { return link_name_; }
  int interface_index() const { return interface_index_; }
  bool enabled() const { return enabled_; }
  bool enabled_persistent() const { return enabled_persistent_; }
  void set_enabled_persistent(bool enabled_persistent) {
    enabled_persistent_ = enabled_persistent;
  }
  mockable Technology technology() const { return technology_; }
  std::string GetTechnologyName() const;
  // Returns the raw hex string of |mac_address_| if it contains value.
  // Otherwise returns an empty string.
  std::string GetMacAddressHexString() const;

  // In WiFi, Ethernet and all other device types except for Cellular, this
  // method is guaranteed to return always a valid Network, so it is safe to
  // dereference the returned value.
  //
  // In Cellular devices, where ephemeral multiplexed network interfaces are
  // supported, this method is not guaranteed to always return a valid Network.
  // The Network lifecycle will be bound to the connection state of the device,
  // and therefore this method will return nullptr when disconnected.
  virtual Network* GetPrimaryNetwork() const;

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

  static constexpr std::string_view kStoragePowered = "Powered";

  // Returns a WeakPtr of the Device.
  base::WeakPtr<Device> AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }

  PropertyStore* mutable_store() { return &store_; }
  const PropertyStore& store() const { return store_; }
  net_base::RTNLHandler* rtnl_handler() { return rtnl_handler_; }

  EventDispatcher* dispatcher() const;

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

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

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

  // Suspend event handler. Called by Manager before the system
  // suspends. This handler, along with any other suspend handlers,
  // will have Manager::kTerminationActionsTimeoutMilliseconds to
  // execute before the system enters the suspend state. |callback|
  // must be invoked after all synchronous and/or asynchronous actions
  // this function performs complete. Code that needs to run on exit should use
  // Manager::AddTerminationAction, rather than OnBeforeSuspend.
  //
  // The default implementation invokes the |callback| immediately, since
  // there is nothing to be done in the general case.
  virtual void OnBeforeSuspend(ResultCallback callback);

  // 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();

  // This method is invoked when the system resumes from suspend temporarily in
  // the "dark resume" state. The system will reenter suspend in
  // Manager::kTerminationActionsTimeoutMilliseconds. |callback| must be invoked
  // after all synchronous and/or asynchronous actions this function performs
  // and/or posts complete.
  //
  // The default implementation invokes the |callback| immediately, since
  // there is nothing to be done in the general case.
  virtual void OnDarkResume(ResultCallback callback);

  // Sets MAC address source for USB Ethernet device.
  virtual void SetUsbEthernetMacAddressSource(const std::string& source,
                                              ResultCallback callback);

  // Renew DHCPv4 lease and invalidate the IPv6 config kept in shill.
  void ForceIPConfigUpdate();

  // Request the WiFi device to roam to AP with |addr|.
  // This call will send Roam command to wpa_supplicant.
  virtual bool RequestRoam(const std::string& addr, Error* error);

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

  // Returns a string formatted as "$ifname $service_log_name", or
  // "$ifname no_service" if |selected_service_| is currently not defined.
  std::string LoggingTag() const;

  // Overrides for Network::EventHandler. See the comments for
  // Network::EventHandler for more details.

  // Updates the state of the current selected service and request network
  // validation if the Service's current configuration does not disable network
  // validation. If network validation is currently disabled, the Service's
  // connection state is set immediately to 'online'.
  void OnConnectionUpdated(int interface_index) override;
  void OnNetworkStopped(int interface_index, bool is_failure) override;
  // Emit a property change signal for the "IPConfigs" property of this device.
  void OnIPConfigsPropertyUpdated(int interface_index) override;

  void set_selected_service_for_testing(ServiceRefPtr service) {
    selected_service_ = service;
  }

  void set_network_for_testing(std::unique_ptr<Network> network) {
    implicit_network_ = std::move(network);
  }

 protected:
  friend class base::RefCounted<Device>;
  FRIEND_TEST(CellularServiceTest, IsAutoConnectable);
  FRIEND_TEST(CellularTest, DefaultLinkDeleted);
  FRIEND_TEST(DeviceTest, AvailableIPConfigs);
  FRIEND_TEST(DeviceTest, FetchTrafficCounters);
  FRIEND_TEST(DeviceTest, GetProperties);
  FRIEND_TEST(DeviceTest, Load);
  FRIEND_TEST(DeviceTest, Save);
  FRIEND_TEST(DeviceTest, SelectedService);
  FRIEND_TEST(DeviceTest, SetEnabledNonPersistent);
  FRIEND_TEST(DeviceTest, SetEnabledPersistent);
  FRIEND_TEST(DeviceTest, Start);
  FRIEND_TEST(DeviceTest, StartFailure);
  FRIEND_TEST(DeviceTest, StartProhibited);
  FRIEND_TEST(DeviceTest, Stop);
  FRIEND_TEST(DeviceTest, StopWithFixedIpParams);
  FRIEND_TEST(DeviceTest, StopWithNetworkInterfaceDisabledAfterward);
  FRIEND_TEST(ManagerTest, ConnectedTechnologies);
  FRIEND_TEST(ManagerTest, DefaultTechnology);
  FRIEND_TEST(ManagerTest, DeviceRegistrationAndStart);
  FRIEND_TEST(ManagerTest, GetEnabledDeviceWithTechnology);
  FRIEND_TEST(ManagerTest, ConnectToMostSecureWiFi);
  FRIEND_TEST(ManagerTest, RefreshAllTrafficCountersTask);
  FRIEND_TEST(ManagerTest, SetEnabledStateForTechnology);
  FRIEND_TEST(ManagerTest, TechnologyEnabledCheck);
  FRIEND_TEST(VirtualDeviceTest, ResetConnection);

  ~Device() override;

  // Each device must implement this method to do the work needed to
  // enable the device to operate for establishing network connections.
  virtual void Start(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.
  virtual void Stop(EnabledStateChangedCallback callback) = 0;

  // Returns true if the associated network interface should be brought down
  // after the device is disabled, or false if that should be done before the
  // device is disabled.
  virtual bool ShouldBringNetworkInterfaceDownAfterDisabled() const;

  // 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(ResultCallback callback, const Error& error);

  // Update the device state to the pending state.
  void UpdateEnabledState();

  // Create the implicit Network object. It's called at constructor when the
  // parameter |use_implicit_network| is true.
  void CreateImplicitNetwork(bool fixed_ip_params);

  // Drops the currently selected service along with its IP configuration and
  // implicit Network connection, if any. Must be reimplemented by classes (e.g.
  // Cellular) that don't require the implicit network.
  virtual void DropConnection();

  // Brings the network interface associated to the implicit Network down. Must
  /// be reimplemented by classes (e.g. Cellular) that don't require the
  // implicit network.
  virtual void BringNetworkInterfaceDown();

  // 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();

  // Check if the interface index provided corresponds to the index of the
  // network interface associated to the primary network. Network events
  // reported in other interfaces will be ignored by the Device class.
  bool IsEventOnPrimaryNetwork(int interface_index);

  // Selects a service to be "current" -- i.e. link-state or configuration
  // events that happen to the device are attributed to this service. Also reset
  // old service state to Idle if its current state is not Failure and
  // |reset_old_service_state| is true.
  void SelectService(const ServiceRefPtr& service,
                     bool reset_old_service_state = true);

  // Reset the Network currently used in the selected service by reloading the
  // one considered primary. This will typically be run during SelectService()
  // but may also happen if technologies silently change the Network used
  // without performing service selection.
  void ResetServiceAttachedNetwork();

  // 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);

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

  void HelpRegisterConstDerivedRpcIdentifier(
      std::string_view name, RpcIdentifier (Device::*get)(Error*));

  void HelpRegisterConstDerivedRpcIdentifiers(
      std::string_view name, RpcIdentifiers (Device::*get)(Error*));

  void HelpRegisterConstDerivedUint64(std::string_view name,
                                      uint64_t (Device::*get)(Error*));

  // By default StorageId is equal to: "device_" + DeviceStorageSuffix()
  // where the latter returns the raw hex string of the MAC address.
  // This can be overridden in subclasses.
  virtual std::string DeviceStorageSuffix() const {
    return GetMacAddressHexString();
  }

  // Property getters reserved for subclasses
  ControlInterface* control_interface() const;
  bool enabled_pending() const { return enabled_pending_; }
  Metrics* metrics() const;
  Manager* manager() const { return manager_; }

  virtual void set_mac_address(net_base::MacAddress mac_address);

  // Emit a given MAC Address via dbus. If std::nullopt is provided, emit the
  // hardware MAC address of the device.
  void EmitMACAddress(
      std::optional<net_base::MacAddress> mac_address = std::nullopt);

 private:
  friend class CellularTest;
  friend class DeviceAdaptorInterface;
  friend class DeviceByteCountTest;
  friend class DevicePortalDetectionTest;
  friend class DeviceTest;
  friend class DevicePortalDetectorTest;
  friend class EthernetTest;
  friend class OpenVPNDriverTest;
  friend class TestDevice;
  friend class VirtualDeviceTest;
  friend class WiFiObjectTest;

  RpcIdentifier GetSelectedServiceRpcIdentifier(Error* error);
  RpcIdentifiers AvailableIPConfigs(Error* error);

  // Atomically update the counters of the old service and the snapshot of the
  // new service. |GetTrafficCountersPatchpanelCallback| calls
  // |GetTrafficCountersCallback| using the |get_traffic_counters_callback_|
  // callback below. This is necessary because the callback that holds a
  // reference to the ServiceRefPtrs needs to be reset to release the
  // references. We can't directly cancel the callback we give to patchpanel
  // client since it expects a OnceCallback.
  void GetTrafficCountersCallback(
      const ServiceRefPtr& old_service,
      const ServiceRefPtr& new_service,
      const std::vector<patchpanel::Client::TrafficCounter>& counters);
  void GetTrafficCountersPatchpanelCallback(
      unsigned int id,
      const std::vector<patchpanel::Client::TrafficCounter>& counters);

  // Asynchronously get all the traffic counters for this device during a
  // selected_service_ change and update the counters and snapshots for the old
  // and new selected_service_ respectively.
  void FetchTrafficCounters(const ServiceRefPtr& old_service,
                            const ServiceRefPtr& new_service);

  // Necessary getter signature for kTypeProperty. Cannot be const.
  std::string GetTechnologyString(Error* error);
  // Necessary getter signature for kAddressProperty. Cannot be const.
  std::string GetMacAddressString(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_;

  std::optional<net_base::MacAddress> mac_address_;

  PropertyStore store_;

  const int interface_index_;
  const std::string link_name_;
  Manager* manager_;
  std::unique_ptr<Network> implicit_network_;
  std::unique_ptr<DeviceAdaptorInterface> adaptor_;
  Technology technology_;

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

  // Cache singleton pointers for performance and test purposes.
  net_base::RTNLHandler* rtnl_handler_;

  // See GetTrafficCountersCallback.
  unsigned int traffic_counter_callback_id_;

  // Maps the callback ID, created when FetchTrafficCounters is called, to the
  // corresponding callback.
  std::map<unsigned int,
           base::OnceCallback<void(
               const std::vector<patchpanel::Client::TrafficCounter>&)>>
      traffic_counters_callback_map_;

  base::WeakPtrFactory<Device> weak_ptr_factory_;
};

}  // namespace shill

#endif  // SHILL_DEVICE_H_
