// Copyright (c) 2012 The Chromium 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 CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
#define CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/network/managed_state.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_handler_callbacks.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_type_pattern.h"
#include "chromeos/network/shill_property_handler.h"

namespace base {
class DictionaryValue;
class ListValue;
class Location;
class Value;
}

namespace chromeos {

class DeviceState;
class NetworkState;
class NetworkStateHandlerObserver;
class NetworkStateHandlerTest;

// Class for tracking the list of visible networks and their properties.
//
// This class maps essential properties from the connection manager (Shill) for
// each visible network. It is not used to change the properties of services or
// devices, only global (manager) properties.
//
// All getters return the currently cached properties. This class is expected to
// keep properties up to date by managing the appropriate Shill observers.
// It will invoke its own more specific observer methods when the specified
// changes occur.
//
// Some notes about NetworkState and GUIDs:
// * A NetworkState exists for all network services stored in a profile, and
//   all "visible" networks (physically connected networks like ethernet and
//   cellular or in-range wifi networks). If the network is stored in a profile,
//   NetworkState.IsInProfile() will return true.
// * "Visible" networks return true for NetworkState.visible().
// * All networks saved to a profile will have a saved GUID that is persistent
//   across sessions.
// * Networks that are not saved to a profile will have a GUID assigned when
//   the initial properties are received. The GUID will be consistent for
//   the duration of a session, even if the network drops out and returns.

class CHROMEOS_EXPORT NetworkStateHandler
    : public internal::ShillPropertyHandler::Listener {
 public:
  typedef std::vector<std::unique_ptr<ManagedState>> ManagedStateList;
  typedef std::vector<const NetworkState*> NetworkStateList;
  typedef std::vector<const DeviceState*> DeviceStateList;

  class TetherSortDelegate {
   public:
    // Sorts |tether_networks| according to the Tether component rules.
    // |tether_networks| contains only networks of type Tether.
    virtual void SortTetherNetworkList(
        ManagedStateList* tether_networks) const = 0;
  };

  enum TechnologyState {
    TECHNOLOGY_UNAVAILABLE,
    TECHNOLOGY_AVAILABLE,
    TECHNOLOGY_UNINITIALIZED,
    TECHNOLOGY_ENABLING,
    TECHNOLOGY_ENABLED,
    TECHNOLOGY_PROHIBITED
  };

  ~NetworkStateHandler() override;

  // Called just before destruction to give observers a chance to remove
  // themselves and disable any networking.
  void Shutdown();

  // Add/remove observers.
  void AddObserver(NetworkStateHandlerObserver* observer,
                   const base::Location& from_here);
  void RemoveObserver(NetworkStateHandlerObserver* observer,
                      const base::Location& from_here);

  // Returns the state for technology |type|. Only
  // NetworkTypePattern::Primitive, ::Mobile, ::Ethernet, and ::Tether are
  // supported.
  TechnologyState GetTechnologyState(const NetworkTypePattern& type) const;
  bool IsTechnologyAvailable(const NetworkTypePattern& type) const {
    return GetTechnologyState(type) != TECHNOLOGY_UNAVAILABLE;
  }
  bool IsTechnologyEnabled(const NetworkTypePattern& type) const {
    return GetTechnologyState(type) == TECHNOLOGY_ENABLED;
  }
  bool IsTechnologyProhibited(const NetworkTypePattern& type) const {
    return GetTechnologyState(type) == TECHNOLOGY_PROHIBITED;
  }
  bool IsTechnologyUninitialized(const NetworkTypePattern& type) const {
    return GetTechnologyState(type) == TECHNOLOGY_UNINITIALIZED;
  }

  // Asynchronously sets the technology enabled property for |type|. Only
  // NetworkTypePattern::Primitive, ::Mobile and ::Ethernet are supported.
  // Note: Modifies Manager state. Calls |error_callback| on failure.
  void SetTechnologyEnabled(
      const NetworkTypePattern& type,
      bool enabled,
      const network_handler::ErrorCallback& error_callback);

  // Sets the Tether technology state. Because Tether networks do not represent
  // real Shill networks, this value must be set by the Tether component rather
  // than being generated by Shill. See TetherDeviceStateManager for more
  // details.
  void SetTetherTechnologyState(TechnologyState technology_state);

  // Sets the scanning state of the Tether technology. Since Tether network
  // scans are not actually performed as part of Shill, this value must be set
  // by the Tether component.
  void SetTetherScanState(bool is_scanning);

  // Asynchronously sets the list of prohibited technologies. The accepted
  // values are the shill network technology identifiers. See also
  // chromeos::onc::Validator::ValidateGlobalNetworkConfiguration().
  void SetProhibitedTechnologies(
      const std::vector<std::string>& prohibited_technologies,
      const network_handler::ErrorCallback& error_callback);

  // Finds and returns a device state by |device_path| or NULL if not found.
  const DeviceState* GetDeviceState(const std::string& device_path) const;

  // Finds and returns a device state by |type|. Returns NULL if not found.
  const DeviceState* GetDeviceStateByType(const NetworkTypePattern& type) const;

  // Returns true if any device of |type| is scanning.
  bool GetScanningByType(const NetworkTypePattern& type) const;

  // Finds and returns a network state by |service_path| or NULL if not found.
  // Note: NetworkState is frequently updated asynchronously, i.e. properties
  // are not always updated all at once. This will contain the most recent
  // value for each property. To receive notifications when a property changes,
  // observe this class and implement NetworkPropertyChanged().
  const NetworkState* GetNetworkState(const std::string& service_path) const;

  // Returns the default network (which includes VPNs) based on the Shill
  // Manager.DefaultNetwork property. Normally this is the same as
  // ConnectedNetworkByType(NetworkTypePattern::Default()), but the timing might
  // differ.
  const NetworkState* DefaultNetwork() const;

  // Returns the primary connected network of matching |type|, otherwise NULL.
  const NetworkState* ConnectedNetworkByType(const NetworkTypePattern& type);

  // Like ConnectedNetworkByType() but returns a connecting network or NULL.
  const NetworkState* ConnectingNetworkByType(
      const NetworkTypePattern& type) const;

  // Like ConnectedNetworkByType() but returns any matching visible network or
  // NULL. Mostly useful for mobile networks where there is generally only one
  // network. Note: O(N).
  const NetworkState* FirstNetworkByType(const NetworkTypePattern& type);

  // Returns the aa:bb formatted hardware (MAC) address for the first connected
  // network matching |type|, or an empty string if none is connected.
  std::string FormattedHardwareAddressForType(const NetworkTypePattern& type);

  // Convenience method to call GetNetworkListByType(visible=true).
  void GetVisibleNetworkListByType(const NetworkTypePattern& type,
                                   NetworkStateList* list);

  // Convenience method for GetVisibleNetworkListByType(Default).
  void GetVisibleNetworkList(NetworkStateList* list);

  // Sets |list| to contain the list of networks with matching |type| and the
  // following properties:
  // |configured_only| - if true only include networks where IsInProfile is true
  // |visible_only| - if true only include networks in the visible Services list
  // |limit| - if > 0 limits the number of results.
  // The returned list contains a copy of NetworkState pointers which should not
  // be stored or used beyond the scope of the calling function (i.e. they may
  // later become invalid, but only on the UI thread). SortNetworkList() will be
  // called if necessary to provide the states in a convenient order (see
  // SortNetworkList for details).
  void GetNetworkListByType(const NetworkTypePattern& type,
                            bool configured_only,
                            bool visible_only,
                            size_t limit,
                            NetworkStateList* list);

  // Finds and returns the NetworkState associated with |service_path| or NULL
  // if not found. If |configured_only| is true, only returns saved entries
  // (IsInProfile is true).
  const NetworkState* GetNetworkStateFromServicePath(
      const std::string& service_path,
      bool configured_only) const;

  // Finds and returns the NetworkState associated with |guid| or NULL if not
  // found. This returns all entries (IsInProfile() may be true or false).
  const NetworkState* GetNetworkStateFromGuid(const std::string& guid) const;

  // Creates a Tether NetworkState that has no underlying shill type or
  // service. When initially created, it does not actually represent a real
  // network. The |guid| provided must be non-empty. If a network with |guid|
  // already exists, this method will do nothing. Use the provided |guid| to
  // refer to and fetch this NetworkState in the future. Note that the
  // |has_connected_to_host| parameter refers to whether the current device has
  // already connected to the Tether host device providing this Tether network
  // in the past.
  void AddTetherNetworkState(const std::string& guid,
                             const std::string& name,
                             const std::string& carrier,
                             int battery_percentage,
                             int signal_strength,
                             bool has_connected_to_host);

  // Updates the Tether properties (carrier, battery percentage, and signal
  // strength) for a network which has already been added via
  // AddTetherNetworkState. Returns whether the update was successful.
  bool UpdateTetherNetworkProperties(const std::string& guid,
                                     const std::string& carrier,
                                     int battery_percentage,
                                     int signal_strength);

  // Updates whether the Tether network with GUID |guid| has connected to the
  // host device before, setting the value to true. Note that there is no way to
  // change this value back to false. If no network with GUID |guid| is
  // registered or if the network is registered and its HasConnectedToHost value
  // was already true, this function does nothing. Returns whether the value was
  // actually changed.
  bool SetTetherNetworkHasConnectedToHost(const std::string& guid);

  // Remove a Tether NetworkState, using the same |guid| passed to
  // AddTetherNetworkState(). If no network with GUID |guid| is registered, this
  // function does nothing. Returns whether the network was actually removed.
  bool RemoveTetherNetworkState(const std::string& guid);

  // Disassociates the Tether network specified by |tether_network_guid| from
  // its associated Wi-Fi network. Returns whether the networkd were
  // successfully disassociated.
  bool DisassociateTetherNetworkStateFromWifiNetwork(
      const std::string& tether_network_guid);

  // Inform NetworkStateHandler that the provided Tether network with the
  // provided guid |tether_network_guid| is associated with the Wi-Fi network
  // with the provided guid |wifi_network_guid|. This Wi-Fi network can now be
  // hidden in the UI, and the Tether network will act as its proxy. Returns
  // false if the association failed (e.g., one or both networks don't exist).
  bool AssociateTetherNetworkStateWithWifiNetwork(
      const std::string& tether_network_guid,
      const std::string& wifi_network_guid);

  // Set the connection_state of the Tether NetworkState corresponding to the
  // provided |guid| to "Disconnected". This will be reflected in the UI.
  void SetTetherNetworkStateDisconnected(const std::string& guid);

  // Set the connection_state of the Tether NetworkState corresponding to the
  // provided |guid| to "Connecting". This will be reflected in the UI.
  void SetTetherNetworkStateConnecting(const std::string& guid);

  // Set the connection_state of the Tether NetworkState corresponding to the
  // provided |guid| to "Connected". This will be reflected in the UI.
  void SetTetherNetworkStateConnected(const std::string& guid);

  void set_tether_sort_delegate(
      const TetherSortDelegate* tether_sort_delegate) {
    tether_sort_delegate_ = tether_sort_delegate;
  }

  // Sets |list| to contain the list of devices.  The returned list contains
  // a copy of DeviceState pointers which should not be stored or used beyond
  // the scope of the calling function (i.e. they may later become invalid, but
  // only on the UI thread).
  void GetDeviceList(DeviceStateList* list) const;

  // Like GetDeviceList() but only returns networks with matching |type|.
  void GetDeviceListByType(const NetworkTypePattern& type,
                           DeviceStateList* list) const;

  // Requests a network scan. This may trigger updates to the network
  // list, which will trigger the appropriate observer calls. If |type| is
  // Cellular, a mobile network scan will be requested if supported.
  void RequestScan(const NetworkTypePattern& type);

  // Requests an update for an existing NetworkState, e.g. after configuring
  // a network. This is a no-op if an update request is already pending. To
  // ensure that a change is picked up, this must be called after Shill
  // acknowledged it (e.g. in the callback of a SetProperties).
  // When the properties are received, NetworkPropertiesUpdated will be
  // signaled for each member of |observers_|, regardless of whether any
  // properties actually changed. Note that this is a no-op for Tether networks.
  void RequestUpdateForNetwork(const std::string& service_path);

  // Informs NetworkStateHandler to notify observers that the properties for
  // the network may have changed. Called e.g. when the proxy properties may
  // have changed.
  void SendUpdateNotificationForNetwork(const std::string& service_path);

  // Clears the last_error value for the NetworkState for |service_path|.
  void ClearLastErrorForNetwork(const std::string& service_path);

  // Sets the list of devices on which portal check is enabled.
  void SetCheckPortalList(const std::string& check_portal_list);

  // Sets a provider id (e.g. extension id) for a hex encoded SSID. If
  // |provider_id| is empty the entry will be erased.
  void SetCaptivePortalProviderForHexSsid(const std::string& hex_ssid,
                                          const std::string& provider_id,
                                          const std::string& provider_name);

  // Sets the Manager.WakeOnLan property. Note: we do not track this state, we
  // only set it.
  void SetWakeOnLanEnabled(bool enabled);

  // Sets the HostName property. Note: we do not track this property, we
  // only set it.
  void SetHostname(const std::string& hostname);

  // Enable or disable network bandwidth throttling, on all interfaces on the
  // system. If |enabled| is true, |upload_rate_kbits| and |download_rate_kbits|
  // are the desired rates (in kbits/s) to throttle to. If |enabled| is false,
  // throttling is off, and the rates are ignored.
  void SetNetworkThrottlingStatus(bool enabled,
                                  uint32_t upload_rate_kbits,
                                  uint32_t download_rate_kbits);

  const std::string& GetCheckPortalListForTest() const {
    return check_portal_list_;
  }

  // Returns the NetworkState of the EthernetEAP service, which contains the
  // EAP parameters used by the ethernet with |service_path|. If |service_path|
  // doesn't refer to an ethernet service or if the ethernet service is not
  // connected using EAP, returns NULL.
  const NetworkState* GetEAPForEthernet(const std::string& service_path);

  const std::string& default_network_path() const {
    return default_network_path_;
  }

  // Sets the |last_error_| property of the matching NetworkState for tests.
  void SetLastErrorForTest(const std::string& service_path,
                           const std::string& error);

  // Constructs and initializes an instance for testing.
  static std::unique_ptr<NetworkStateHandler> InitializeForTest();

  // Default set of comma separated interfaces on which to enable
  // portal checking.
  static const char kDefaultCheckPortalList[];

 protected:
  friend class NetworkHandler;
  NetworkStateHandler();

  // ShillPropertyHandler::Listener overrides.

  // This adds new entries to |network_list_| or |device_list_| and deletes any
  // entries that are no longer in the list.
  void UpdateManagedList(ManagedState::ManagedType type,
                         const base::ListValue& entries) override;

  // The list of profiles changed (i.e. a user has logged in). Re-request
  // properties for all services since they may have changed.
  void ProfileListChanged() override;

  // Parses the properties for the network service or device. Mostly calls
  // managed->PropertyChanged(key, value) for each dictionary entry.
  void UpdateManagedStateProperties(
      ManagedState::ManagedType type,
      const std::string& path,
      const base::DictionaryValue& properties) override;

  // Called by ShillPropertyHandler when a watched service property changes.
  void UpdateNetworkServiceProperty(const std::string& service_path,
                                    const std::string& key,
                                    const base::Value& value) override;

  // Called by ShillPropertyHandler when a watched device property changes.
  void UpdateDeviceProperty(const std::string& device_path,
                            const std::string& key,
                            const base::Value& value) override;

  // Called by ShillPropertyHandler when a watched network or device
  // IPConfig property changes.
  void UpdateIPConfigProperties(
      ManagedState::ManagedType type,
      const std::string& path,
      const std::string& ip_config_path,
      const base::DictionaryValue& properties) override;

  // Called by ShillPropertyHandler when the portal check list manager property
  // changes.
  void CheckPortalListChanged(const std::string& check_portal_list) override;

  // Called by ShillPropertyHandler when a technology list changes.
  void TechnologyListChanged() override;

  // Called by |shill_property_handler_| when the service or device list has
  // changed and all entries have been updated. This updates the list and
  // notifies observers.
  void ManagedStateListChanged(ManagedState::ManagedType type) override;

  // Called when the default network service changes. Sets default_network_path_
  // and notifies listeners.
  void DefaultNetworkServiceChanged(const std::string& service_path) override;

  // Called after construction. Called explicitly by tests after adding
  // test observers.
  void InitShillPropertyHandler();

 private:
  typedef std::map<std::string, std::string> SpecifierGuidMap;
  friend class NetworkStateHandlerTest;
  FRIEND_TEST_ALL_PREFIXES(NetworkStateHandlerTest, NetworkStateHandlerStub);

  // Sorts the network list. Called when all network updates have been received,
  // or when the network list is requested but the list is in an unsorted state.
  // Networks are sorted as follows, maintaining the existing relative ordering:
  // * Connected or connecting networks (should be listed first by Shill)
  // * Visible non-wifi networks
  // * Visible wifi networks
  // * Hidden (wifi) networks
  // If |ensure_cellular| is true, call EnsureCellularNetwork (which may
  // remove a network from the list).
  void SortNetworkList(bool ensure_cellular);

  // Updates UMA stats. Called once after all requested networks are updated.
  void UpdateNetworkStats();

  // NetworkState specific method for UpdateManagedStateProperties which
  // notifies observers.
  void UpdateNetworkStateProperties(NetworkState* network,
                                    const base::DictionaryValue& properties);

  // Ensure a valid GUID for NetworkState.
  void UpdateGuid(NetworkState* network);

  // Look for a matching captive portal provider in
  // |hex_ssid_to_captive_portal_provider_map_|.
  void UpdateCaptivePortalProvider(NetworkState* network);

  // Cellular networks may not have an associated Shill Service (e.g. when the
  // SIM is locked or a mobile network is not available). To simplify the UI,
  // if a Cellular Device exists |cellular_networks| will be modified to contain
  // exactly one network, creating a default network if necessary.
  void EnsureCellularNetwork(ManagedStateList* cellular_networks);

  // Sends NetworkListChanged() to observers and logs an event.
  void NotifyNetworkListChanged();

  // Sends DeviceListChanged() to observers and logs an event.
  void NotifyDeviceListChanged();

  // Non-const getters for managed entries. These are const so that they can
  // be called by Get[Network|Device]State, even though they return non-const
  // pointers.
  DeviceState* GetModifiableDeviceState(const std::string& device_path) const;
  NetworkState* GetModifiableNetworkState(
      const std::string& service_path) const;
  NetworkState* GetModifiableNetworkStateFromGuid(
      const std::string& guid) const;
  ManagedState* GetModifiableManagedState(const ManagedStateList* managed_list,
                                          const std::string& path) const;

  // Gets the list specified by |type|.
  ManagedStateList* GetManagedList(ManagedState::ManagedType type);

  // Helper function that calls NotifyNetworkConnectionStateChanged and,
  // for the default network, OnDefaultNetworkConnectionStateChanged and
  // NotifyDefaultNetworkChanged.
  void OnNetworkConnectionStateChanged(NetworkState* network);

  // Verifies the connection state of the default network. Returns false
  // if the connection state change should be ignored.
  bool VerifyDefaultNetworkConnectionStateChange(NetworkState* network);

  // Notifies observers when a network's connection state changes.
  void NotifyNetworkConnectionStateChanged(NetworkState* network);

  // Notifies observers when the default network or its properties change.
  void NotifyDefaultNetworkChanged();

  // Notifies observers about changes to |network|, including IPConfg.
  void NotifyNetworkPropertiesUpdated(const NetworkState* network);

  // Notifies observers about changes to |device|, including IPConfigs.
  void NotifyDevicePropertiesUpdated(const DeviceState* device);

  // Called to ask observers to scan for networks.
  void NotifyScanRequested();

  // Called whenever Device.Scanning state transitions to false.
  void NotifyScanCompleted(const DeviceState* device);

  // Helper function to log property updated events.
  void LogPropertyUpdated(const ManagedState* network,
                          const std::string& key,
                          const base::Value& value);

  // Returns one technology type for |type|. This technology will be the
  // highest priority technology in the type pattern.
  std::string GetTechnologyForType(const NetworkTypePattern& type) const;

  // Returns all the technology types for |type|.
  std::vector<std::string> GetTechnologiesForType(
      const NetworkTypePattern& type) const;

  // Adds Tether networks to |list|, limiting the maximum size of |list| to be
  // |limit|. If |get_active| is true, only active (i.e., connecting/connected)
  // networks will be added; otherwise, only inactive networks will be added.
  // The returned list contains a copy of NetworkState pointers which
  // should not be stored or used beyond the scope of the calling
  // function (i.e., they may later become invalid, but only on the UI thread).
  // See AddTetherNetworkState() for more information about Tether networks.
  void AppendTetherNetworksToList(bool get_active,
                                  size_t limit,
                                  NetworkStateList* list);

  // Set the connection_state of a Tether NetworkState corresponding to the
  // provided |guid|.
  void SetTetherNetworkStateConnectionState(
      const std::string& guid,
      const std::string& connection_state);

  // Ensures that the Tether DeviceState is present in |device_list_| if
  // |tether_technology_state_| is not TECHNOLOGY_UNAVAILABLE and ensures that
  // it is not present in |device_list_| if it is TECHNOLOGY_UNAVAILABLE.
  void EnsureTetherDeviceState();

  // Shill property handler instance, owned by this class.
  std::unique_ptr<internal::ShillPropertyHandler> shill_property_handler_;

  // Observer list
  base::ObserverList<NetworkStateHandlerObserver, true> observers_;

  // List of managed network states
  ManagedStateList network_list_;

  // List of managed Tether network states, which exist separately from
  // |network_list_|.
  ManagedStateList tether_network_list_;

  // Set to true when the network list is sorted, cleared when network updates
  // arrive. Used to trigger sorting when needed.
  bool network_list_sorted_ = false;

  // List of managed device states
  ManagedStateList device_list_;

  // Keeps track of the default network for notifying observers when it changes.
  std::string default_network_path_;

  // List of interfaces on which portal check is enabled.
  std::string check_portal_list_;

  // Map of network specifiers to guids. Contains an entry for each
  // NetworkState that is not saved in a profile.
  SpecifierGuidMap specifier_guid_map_;

  // Map of hex SSIDs to captive portal provider info.
  // Used to set NetworkState::captive_portal_provider_.
  std::map<std::string, NetworkState::CaptivePortalProviderInfo>
      hex_ssid_to_captive_portal_provider_map_;

  // The state corresponding to the Tether device type. This value is managed by
  // the Tether component.
  TechnologyState tether_technology_state_ =
      TechnologyState::TECHNOLOGY_UNAVAILABLE;

  // Not owned by this instance.
  const TetherSortDelegate* tether_sort_delegate_ = nullptr;

  // Ensure that Shutdown() gets called exactly once.
  bool did_shutdown_ = false;

  // Ensure that we do not delete any networks while notifying observers.
  bool notifying_network_observers_ = false;

  SEQUENCE_CHECKER(sequence_checker_);

  DISALLOW_COPY_AND_ASSIGN(NetworkStateHandler);
};

}  // namespace chromeos

#endif  // CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
