// 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_ETHERNET_
#define SHILL_ETHERNET_

#include <string>

#include <base/cancelable_callback.h>
#include <base/memory/scoped_ptr.h>
#include <base/memory/weak_ptr.h>

#include "shill/certificate_file.h"
#include "shill/device.h"
#include "shill/supplicant_eap_state_handler.h"
#include "shill/event_dispatcher.h"
#include "shill/refptr_types.h"
#include "shill/supplicant_event_delegate_interface.h"

namespace shill {

class CertificateFile;
class EapListener;
class EthernetEapProvider;
class NSS;
class ProxyFactory;
class SupplicantEAPStateHandler;
class SupplicantInterfaceProxyInterface;
class SupplicantProcessProxyInterface;

class Ethernet : public Device, public SupplicantEventDelegateInterface {
 public:
  Ethernet(ControlInterface *control_interface,
           EventDispatcher *dispatcher,
           Metrics *metrics,
           Manager *manager,
           const std::string& link_name,
           const std::string &address,
           int interface_index);
  virtual ~Ethernet();

  virtual void Start(Error *error, const EnabledStateChangedCallback &callback);
  virtual void Stop(Error *error, const EnabledStateChangedCallback &callback);
  virtual void LinkEvent(unsigned int flags, unsigned int change);
  virtual void ConnectTo(EthernetService *service);
  virtual void DisconnectFrom(EthernetService *service);

  // Test to see if conditions are correct for EAP authentication (both
  // credentials and a remote EAP authenticator is present) and initiate
  // an authentication if possible.
  virtual void TryEapAuthentication();

  // Implementation of SupplicantEventDelegateInterface.  These methods
  // are called by SupplicantInterfaceProxy, in response to events from
  // wpa_supplicant.
  virtual void BSSAdded(
      const ::DBus::Path &BSS,
      const std::map<std::string, ::DBus::Variant> &properties);
  virtual void BSSRemoved(const ::DBus::Path &BSS);
  virtual void Certification(
      const std::map<std::string, ::DBus::Variant> &properties);
  virtual void EAPEvent(
      const std::string &status, const std::string &parameter);
  virtual void PropertiesChanged(
      const std::map<std::string, ::DBus::Variant> &properties);
  virtual void ScanDone();

 private:
  friend class EthernetTest;

  // Return a pointer to the EAP provider for Ethernet devices.
  EthernetEapProvider *GetEapProvider();

  // Return a reference to the shared service that contains EAP credentials
  // for Ethernet.
  ServiceConstRefPtr GetEapService();

  // Invoked by |eap_listener_| when an EAP authenticator is detected.
  void OnEapDetected();

  // Start and stop a supplicant instance on this link.
  bool StartSupplicant();
  void StopSupplicant();

  // Start the EAP authentication process.
  bool StartEapAuthentication();

  // Change our EAP authentication state.
  void SetIsEapAuthenticated(bool is_eap_authenticated);

  // Callback tasks run as a result of event delegate methods.
  void CertificationTask(const std::string &subject, uint32 depth);
  void EAPEventTask(const std::string &status, const std::string &parameter);
  void SupplicantStateChangedTask(const std::string &state);

  // Callback task run as a result of TryEapAuthentication().
  void TryEapAuthenticationTask();

  EthernetServiceRefPtr service_;
  bool link_up_;

  // Track whether we have completed EAP authentication successfully.
  bool is_eap_authenticated_;

  // Track whether an EAP authenticator has been detected on this link.
  bool is_eap_detected_;
  scoped_ptr<EapListener> eap_listener_;

  // Track the progress of EAP authentication.
  SupplicantEAPStateHandler eap_state_handler_;

  // Proxy instances used to talk to wpa_supplicant.
  scoped_ptr<SupplicantProcessProxyInterface> supplicant_process_proxy_;
  scoped_ptr<SupplicantInterfaceProxyInterface> supplicant_interface_proxy_;
  std::string supplicant_interface_path_;
  std::string supplicant_network_path_;

  // NSS and certificate file instances are needed to generate public key
  // data for remote authentication.
  NSS *nss_;
  CertificateFile certificate_file_;

  // Make sure TryEapAuthenticationTask is only queued for execution once
  // at a time.
  base::CancelableClosure try_eap_authentication_callback_;

  // Store cached copy of proxy factory singleton for speed/ease of testing.
  ProxyFactory *proxy_factory_;

  base::WeakPtrFactory<Ethernet> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(Ethernet);
};

}  // namespace shill

#endif  // SHILL_ETHERNET_
