// 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_WIFI_SERVICE_H_
#define SHILL_WIFI_SERVICE_H_

#include <set>
#include <string>
#include <vector>

#include <base/memory/scoped_ptr.h>

#include "shill/dbus_properties.h"
#include "shill/dbus_proxies/supplicant-interface.h"
#include "shill/event_dispatcher.h"
#include "shill/key_value_store.h"
#include "shill/refptr_types.h"
#include "shill/service.h"

namespace shill {

class CertificateFile;
class ControlInterface;
class EventDispatcher;
class Error;
class Manager;
class Metrics;
class WiFiProvider;

class WiFiService : public Service {
 public:
  // TODO(pstew): Storage constants shouldn't need to be public
  // crbug.com/208736
  static const char kStorageHiddenSSID[];
  static const char kStorageMode[];
  static const char kStoragePassphrase[];
  static const char kStorageSecurity[];
  static const char kStorageSecurityClass[];
  static const char kStorageSSID[];

  WiFiService(ControlInterface *control_interface,
              EventDispatcher *dispatcher,
              Metrics *metrics,
              Manager *manager,
              WiFiProvider *provider,
              const std::vector<uint8_t> &ssid,
              const std::string &mode,
              const std::string &security,
              bool hidden_ssid);
  ~WiFiService();

  // Inherited from Service.
  virtual void Connect(Error *error, const char *reason);
  virtual void Disconnect(Error *error, const char *reason);
  virtual bool Is8021x() const;

  virtual void AddEndpoint(const WiFiEndpointConstRefPtr &endpoint);
  virtual void RemoveEndpoint(const WiFiEndpointConstRefPtr &endpoint);
  virtual int GetEndpointCount() const { return endpoints_.size(); }

  // Called to update the identity of the currently connected endpoint.
  // To indicate that there is no currently connect endpoint, call with
  // |endpoint| set to NULL.
  virtual void NotifyCurrentEndpoint(const WiFiEndpointConstRefPtr &endpoint);
  // Called to inform of changes in the properties of an endpoint.
  // (Not necessarily the currently connected endpoint.)
  virtual void NotifyEndpointUpdated(const WiFiEndpointConstRefPtr &endpoint);

  // wifi_<MAC>_<BSSID>_<mode_string>_<security_string>
  std::string GetStorageIdentifier() const;
  static bool ParseStorageIdentifier(const std::string &storage_name,
                                     std::string *address,
                                     std::string *mode,
                                     std::string *security);

  // Iterate over |storage| looking for WiFi servces with "old-style"
  // properties that don't include explicit type/mode/security, and add
  // these properties.  Returns true if any entries were fixed.
  static bool FixupServiceEntries(StoreInterface *storage);

  // Validate |mode| against all valid and supported service modes.
  static bool IsValidMode(const std::string &mode);

  // Validate |method| against all valid and supported security methods.
  static bool IsValidSecurityMethod(const std::string &method);

  const std::string &mode() const { return mode_; }
  const std::string &key_management() const { return GetEAPKeyManagement(); }
  const std::vector<uint8_t> &ssid() const { return ssid_; }
  const std::string &bssid() const { return bssid_; }
  const std::vector<uint16_t> &frequency_list() const {
    return frequency_list_;
  }
  uint16_t physical_mode() const { return physical_mode_; }
  uint16_t frequency() const { return frequency_; }

  // WiFi services can load from profile entries other than their current
  // storage identifier.  Override the methods from the parent Service
  // class which pertain to whether this service may be loaded from |storage|.
  virtual std::string GetLoadableStorageIdentifier(
      const StoreInterface &storage) const;
  virtual bool IsLoadableFrom(const StoreInterface &storage) const;

  // Overrride Load and Save from parent Service class.  We will call
  // the parent method.
  virtual bool Load(StoreInterface *storage);
  virtual bool Save(StoreInterface *storage);
  virtual bool Unload();

  // Override SetState from parent Service class.  We will call the
  // parent method.
  virtual void SetState(ConnectState state) override;

  virtual bool HasEndpoints() const { return !endpoints_.empty(); }
  virtual bool IsVisible() const override;
  bool IsSecurityMatch(const std::string &security) const;

  // Used by WiFi objects to indicate that the credentials for this network
  // have been called into question.  This method returns true if given this
  // suspicion, if it is probable that indeed these credentials are likely
  // to be incorrect.  Credentials that have never been used before are
  // considered suspect by default, while those which have been used
  // successfully in the past must have this method called a number of times
  // since the last time ResetSuspectedCredentialsFailures() was called.
  virtual bool AddSuspectedCredentialFailure();
  virtual void ResetSuspectedCredentialFailures();

  bool hidden_ssid() const { return hidden_ssid_; }
  bool ieee80211w_required() const { return ieee80211w_required_; }

  void InitializeCustomMetrics() const;
  virtual void SendPostReadyStateMetrics(
      int64_t time_resume_to_ready_milliseconds) const;

  // Clear any cached credentials stored in wpa_supplicant related to |this|.
  // This will disconnect this service if it is currently connected.
  void ClearCachedCredentials();

  // Override from parent Service class to correctly update connectability
  // when the EAP credentials change for 802.1x networks.
  void OnEapCredentialsChanged();

  // Called by WiFiService to reset state associated with prior success
  // of a connection with particular EAP credentials or a passphrase.
  void OnCredentialChange();

  // Override from parent Service class to register hidden services once they
  // have been configured.
  virtual void OnProfileConfigured();

  // Called by WiFiProvider to reset the WiFi device reference on shutdown.
  virtual void ResetWiFi();

  // Called by WiFi to retrieve configuration parameters for wpa_supplicant.
  virtual DBusPropertiesMap GetSupplicantConfigurationParameters() const;

  // "wpa", "rsn" and "psk" are equivalent from a configuration perspective.
  // This function maps them all into "psk".
  static std::string GetSecurityClass(const std::string &security);

  virtual bool IsAutoConnectable(const char **reason) const;

  // Signal level in dBm.  If no current endpoint, returns
  // std::numeric_limits<int>::min().
  int16_t SignalLevel() const;

  void set_expecting_disconnect(bool val) { expecting_disconnect_ = val; }
  bool expecting_disconnect() const { return expecting_disconnect_; }

 protected:
  virtual void SetEAPKeyManagement(const std::string &key_management);
  virtual std::string GetTethering(Error *error) const override;

 private:
  friend class WiFiServiceSecurityTest;
  friend class WiFiServiceTest;  // SetPassphrase
  friend class WiFiServiceUpdateFromEndpointsTest;  // SignalToStrength
  FRIEND_TEST(MetricsTest, WiFiServicePostReady);
  FRIEND_TEST(MetricsTest, WiFiServicePostReadyAdHoc);
  FRIEND_TEST(MetricsTest, WiFiServicePostReadyEAP);
  FRIEND_TEST(WiFiMainTest, CurrentBSSChangedUpdateServiceEndpoint);
  FRIEND_TEST(WiFiProviderTest, OnEndpointAddedWithSecurity);  // security_
  FRIEND_TEST(WiFiServiceTest, AutoConnect);
  FRIEND_TEST(WiFiServiceTest, ClearWriteOnlyDerivedProperty);  // passphrase_
  FRIEND_TEST(WiFiServiceTest, ComputeCipher8021x);
  FRIEND_TEST(WiFiServiceTest, ConnectTask8021x);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskDynamicWEP);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskPSK);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskRSN);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskWEP);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA);
  FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA80211w);
  FRIEND_TEST(WiFiServiceTest, GetTethering);
  FRIEND_TEST(WiFiServiceTest, IsAutoConnectable);
  FRIEND_TEST(WiFiServiceTest, LoadHidden);
  FRIEND_TEST(WiFiServiceTest, LoadAndUnloadPassphrase);
  FRIEND_TEST(WiFiServiceTest, SecurityFromCurrentEndpoint);  // GetSecurity
  FRIEND_TEST(WiFiServiceTest, SetPassphraseResetHasEverConnected);
  FRIEND_TEST(WiFiServiceTest, SetPassphraseRemovesCachedCredentials);
  FRIEND_TEST(WiFiServiceTest, SignalToStrength);  // SignalToStrength
  FRIEND_TEST(WiFiServiceTest, SuspectedCredentialFailure);
  FRIEND_TEST(WiFiServiceTest, UpdateSecurity);  // SetEAPKeyManagement

  static const char kAutoConnNoEndpoint[];
  static const char kAnyDeviceAddress[];
  static const int kSuspectedCredentialFailureThreshold;

  // Override the base clase implementation, because we need to allow
  // arguments that aren't base class methods.
  void HelpRegisterConstDerivedString(
      const std::string &name,
      std::string(WiFiService::*get)(Error *error));
  void HelpRegisterDerivedString(
      const std::string &name,
      std::string(WiFiService::*get)(Error *error),
      bool(WiFiService::*set)(const std::string &value, Error *error));
  void HelpRegisterWriteOnlyDerivedString(
      const std::string &name,
      bool(WiFiService::*set)(const std::string &value, Error *error),
      void(WiFiService::*clear)(Error *error),
      const std::string *default_value);

  std::string GetDeviceRpcId(Error *error) const;

  void ClearPassphrase(Error *error);
  void UpdateConnectable();
  void UpdateFromEndpoints();
  void UpdateSecurity();

  static CryptoAlgorithm ComputeCipher8021x(
      const std::set<WiFiEndpointConstRefPtr> &endpoints);
  static void ValidateWEPPassphrase(const std::string &passphrase,
                                    Error *error);
  static void ValidateWPAPassphrase(const std::string &passphrase,
                                    Error *error);
  static void ParseWEPPassphrase(const std::string &passphrase,
                                 int *key_index,
                                 std::vector<uint8_t> *password_bytes,
                                 Error *error);
  static bool CheckWEPIsHex(const std::string &passphrase, Error *error);
  static bool CheckWEPKeyIndex(const std::string &passphrase, Error *error);
  static bool CheckWEPPrefix(const std::string &passphrase, Error *error);

  // Maps a signal value, in dBm, to a "strength" value, from
  // |Service::kStrengthMin| to |Service:kStrengthMax|.
  static uint8_t SignalToStrength(int16_t signal_dbm);

  // Create a default group name for this WiFi service.
  std::string GetDefaultStorageIdentifier() const;

  // Return the security of this service.  If connected, the security
  // reported from the currently connected endpoint is returned.  Otherwise
  // the configured security for the service is returned.
  std::string GetSecurity(Error *error);

  // Profile data for a WPA/RSN service can be stored under a number of
  // different security types.  These functions create different storage
  // property lists based on whether they are saved with their generic
  // "psk" name or if they use the (legacy) specific "wpa" or "rsn" names.
  KeyValueStore GetStorageProperties() const;

  // Validate then apply a passphrase for this service.
  bool SetPassphrase(const std::string &passphrase, Error *error);

  // Select a WiFi device (e.g, for connecting a hidden service with no
  // endpoints).
  WiFiRefPtr ChooseDevice();

  void SetWiFi(const WiFiRefPtr &new_wifi);

  // Properties
  std::string passphrase_;
  bool need_passphrase_;
  const std::string security_;
  // TODO(cmasone): see if the below can be pulled from the endpoint associated
  // with this service instead.
  const std::string mode_;
  std::string auth_mode_;
  bool hidden_ssid_;
  uint16_t frequency_;
  std::vector<uint16_t> frequency_list_;
  uint16_t physical_mode_;
  // The raw dBm signal strength from the associated endpoint.
  int16_t raw_signal_strength_;
  std::string hex_ssid_;
  std::string storage_identifier_;
  std::string bssid_;
  Stringmap vendor_information_;
  // The country code reported by the current endpoint.
  std::string country_code_;
  // If |security_| == kSecurity8021x, the crypto algorithm being used.
  // (Otherwise, crypto algorithm is implied by |security_|.)
  CryptoAlgorithm cipher_8021x_;

  // Track the number of consecutive times our current credentials have
  // been called into question.
  int suspected_credential_failures_;

  // Track whether or not we've warned about large signal values.
  // Used to avoid spamming the log.
  static bool logged_signal_warning;

  WiFiRefPtr wifi_;
  std::set<WiFiEndpointConstRefPtr> endpoints_;
  WiFiEndpointConstRefPtr current_endpoint_;
  const std::vector<uint8_t> ssid_;
  // Track whether IEEE 802.11w (Protected Management Frame) support is
  // mandated by one or more endpoints we have seen that provide this service.
  bool ieee80211w_required_;
  // Flag indicating if service disconnect is initiated by user for
  // connecting to other service.
  bool expecting_disconnect_;
  scoped_ptr<CertificateFile> certificate_file_;
  // Bare pointer is safe because WiFi service instances are owned by
  // the WiFiProvider and are guaranteed to be deallocated by the time
  // the WiFiProvider is.
  WiFiProvider *provider_;

  DISALLOW_COPY_AND_ASSIGN(WiFiService);
};

}  // namespace shill

#endif  // SHILL_WIFI_SERVICE_H_
