//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef SHILL_DEVICE_INFO_H_
#define SHILL_DEVICE_INFO_H_

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

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/files/file_path.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/device.h"
#include "shill/net/byte_string.h"
#include "shill/net/ip_address.h"
#include "shill/net/rtnl_listener.h"
#include "shill/net/shill_time.h"
#include "shill/technology.h"

namespace shill {

class Manager;
class Metrics;
class RoutingTable;
class RTNLHandler;
class RTNLMessage;
class Sockets;

#if !defined(DISABLE_WIFI)
class NetlinkManager;
class Nl80211Message;
#endif  // DISABLE_WIFI

class DeviceInfo : public base::SupportsWeakPtr<DeviceInfo> {
 public:
  struct AddressData {
    AddressData()
        : address(IPAddress::kFamilyUnknown), flags(0), scope(0) {}
    AddressData(const IPAddress& address_in,
                unsigned char flags_in,
                unsigned char scope_in)
        : address(address_in), flags(flags_in), scope(scope_in) {}
    IPAddress address;
    unsigned char flags;
    unsigned char scope;
  };

  // Device name prefix for modem pseudo devices used in testing.
  static const char kModemPseudoDeviceNamePrefix[];
  // Device name prefix for virtual ethernet devices used in testing.
  static const char kEthernetPseudoDeviceNamePrefix[];
  // Device name prefixes for virtual devices that should be ignored.
  static const char* const kIgnoredDeviceNamePrefixes[];
  // Time interval for polling for link statistics.
  static const int kRequestLinkStatisticsIntervalMilliseconds;

  DeviceInfo(ControlInterface* control_interface,
             EventDispatcher* dispatcher,
             Metrics* metrics,
             Manager* manager);
  virtual ~DeviceInfo();

  virtual void AddDeviceToBlackList(const std::string& device_name);
  virtual void RemoveDeviceFromBlackList(const std::string& device_name);
  virtual bool IsDeviceBlackListed(const std::string& device_name);
  void Start();
  void Stop();

  std::vector<std::string> GetUninitializedTechnologies() const;

  // Adds |device| to this DeviceInfo instance so that we can handle its link
  // messages, and registers it with the manager.
  virtual void RegisterDevice(const DeviceRefPtr& device);

  // Remove |device| from this DeviceInfo.  This function should only
  // be called for cellular devices because the lifetime of the
  // cellular devices is controlled by the Modem object and its
  // communication to modem manager, rather than by RTNL messages.
  virtual void DeregisterDevice(const DeviceRefPtr& device);

  virtual DeviceRefPtr GetDevice(int interface_index) const;
  virtual bool GetMACAddress(int interface_index, ByteString* address) const;

  // Queries the kernel for a MAC address for |interface_index|.  Returns an
  // empty ByteString on failure.
  virtual ByteString GetMACAddressFromKernel(int interface_index) const;

  // Queries the kernel for the MAC address of |peer| on |interface_index|.
  // Returns true and populates |mac_address| on success, otherwise returns
  // false.
  virtual bool GetMACAddressOfPeer(int interface_index,
                                   const IPAddress& peer,
                                   ByteString* mac_address) const;

  virtual bool GetFlags(int interface_index, unsigned int* flags) const;
  virtual bool GetByteCounts(int interface_index,
                             uint64_t* rx_bytes, uint64_t* tx_bytes) const;
  virtual bool GetAddresses(int interface_index,
                            std::vector<AddressData>* addresses) const;

  // Flush all addresses associated with |interface_index|.
  virtual void FlushAddresses(int interface_index) const;
  // Returns whether this interface does not have |this_address|
  // but has another non-temporary address of the same family.
  virtual bool HasOtherAddress(
      int interface_index, const IPAddress& this_address) const;

  // Get the preferred globally scoped IPv6 address for |interface_index|.
  // This method returns true and sets |address| if a primary IPv6 address
  // exists.  Otherwise it returns false and leaves |address| unmodified.
  virtual bool GetPrimaryIPv6Address(int interface_index, IPAddress* address);

  // Get the IPv6 DNS server addresses for |interface_index|. This method
  // returns true and sets |address_list| and |life_time_seconds| if the IPv6
  // DNS server addresses exists. Otherwise, it returns false and leave
  // |address_list| and |life_time_seconds| unmodified. |life_time_seconds|
  // indicates the number of the seconds the DNS server is still valid for at
  // the time of this function call. Value of 0 means the DNS server is not
  // valid anymore, and value of 0xFFFFFFFF means the DNS server is valid
  // forever.
  virtual bool GetIPv6DnsServerAddresses(int interface_index,
                                         std::vector<IPAddress>* address_list,
                                         uint32_t* life_time_seconds);

  // Returns true if any of the addresses on |interface_index| are on the
  // same network prefix as |address|.
  virtual bool HasDirectConnectivityTo(
      int interface_index, const IPAddress& address) const;

  virtual bool CreateTunnelInterface(std::string* interface_name) const;
  virtual int OpenTunnelInterface(const std::string& interface_name) const;
  virtual bool DeleteInterface(int interface_index) const;

  // Returns the interface index for |interface_name| or -1 if unknown.
  virtual int GetIndex(const std::string& interface_name) const;

  // Sets the system hostname to |hostname|.
  virtual bool SetHostname(const std::string& hostname) const;

 private:
  friend class DeviceInfoDelayedCreationTest;
  friend class DeviceInfoTechnologyTest;
  friend class DeviceInfoTest;
  FRIEND_TEST(CellularTest, StartLinked);
  FRIEND_TEST(DeviceInfoTest, CreateDeviceWiMax);
  FRIEND_TEST(DeviceInfoTest, DeviceRemovedEvent);
  FRIEND_TEST(DeviceInfoTest, GetUninitializedTechnologies);
  FRIEND_TEST(DeviceInfoTest, HasSubdir);  // For HasSubdir.
  FRIEND_TEST(DeviceInfoTest, IPv6AddressChanged);  // For infos_.
  FRIEND_TEST(DeviceInfoTest, RequestLinkStatistics);
  FRIEND_TEST(DeviceInfoTest, StartStop);
  FRIEND_TEST(DeviceInfoTest, IPv6DnsServerAddressesChanged);  // For infos_.

  struct Info {
    Info()
        : flags(0),
          rx_bytes(0),
          tx_bytes(0),
          has_addresses_only(false),
          technology(Technology::kUnknown)
    {}

    DeviceRefPtr device;
    std::string name;
    ByteString mac_address;
    std::vector<AddressData> ip_addresses;
    std::vector<IPAddress> ipv6_dns_server_addresses;
    uint32_t ipv6_dns_server_lifetime_seconds;
    time_t ipv6_dns_server_received_time_seconds;
    unsigned int flags;
    uint64_t rx_bytes;
    uint64_t tx_bytes;

    // This flag indicates that link information has not been retrieved yet;
    // only the ip_addresses field is valid.
    bool has_addresses_only;

    Technology::Identifier technology;
  };

  // Root of the kernel sysfs directory holding network device info.
  static const char kDeviceInfoRoot[];
  // Name of the "cdc_ether" driver.  This driver is not included in the
  // kModemDrivers list because we need to do additional checking.
  static const char kDriverCdcEther[];
  // Name of the "cdc_ncm" driver.  This driver is not included in the
  // kModemDrivers list because we need to do additional checking.
  static const char kDriverCdcNcm[];
  // Name of the GDM WiMAX driver.
  static const char kDriverGdmWiMax[];
  // Name of the virtio network driver.
  static const char kDriverVirtioNet[];
  // Sysfs path to a device uevent file.
  static const char kInterfaceUevent[];
  // Content of a device uevent file that indicates it is a bridge device.
  static const char kInterfaceUeventBridgeSignature[];
  // Content of a device uevent file that indicates it is a wifi device.
  static const char kInterfaceUeventWifiSignature[];
  // Sysfs path to a device via its interface name.
  static const char kInterfaceDevice[];
  // Sysfs path to the driver of a device via its interface name.
  static const char kInterfaceDriver[];
  // Sysfs path to the file that is used to determine if this is tun device.
  static const char kInterfaceTunFlags[];
  // Sysfs path to the file that is used to determine if a wifi device is
  // operating in monitor mode.
  static const char kInterfaceType[];
  // Modem drivers that we support.
  static const char* const kModemDrivers[];
  // Path to the tun device.
  static const char kTunDeviceName[];
  // Time to wait before registering devices which need extra time to detect.
  static const int kDelayedDeviceCreationSeconds;

  // Create a Device object for the interface named |linkname|, with a
  // string-form MAC address |address|, whose kernel interface index
  // is |interface_index| and detected technology is |technology|.
  virtual DeviceRefPtr CreateDevice(const std::string& link_name,
                                    const std::string& address,
                                    int interface_index,
                                    Technology::Identifier technology);

  // Return the FilePath for a given |path_name| in the device sysinfo for
  // a specific interface |iface_name|.
  base::FilePath GetDeviceInfoPath(const std::string& iface_name,
                             const std::string& path_name);
  // Return the contents of the device info file |path_name| for interface
  // |iface_name| in output parameter |contents_out|.  Returns true if file
  // read succeeded, false otherwise.
  bool GetDeviceInfoContents(const std::string& iface_name,
                             const std::string& path_name,
                             std::string* contents_out);

  // Return the filepath for the target of the device info symbolic link
  // |path_name| for interface |iface_name| in output parameter |path_out|.
  // Returns true if symbolic link read succeeded, false otherwise.
  bool GetDeviceInfoSymbolicLink(const std::string& iface_name,
                                 const std::string& path_name,
                                 base::FilePath* path_out);
  // Classify the device named |iface_name|, and return an identifier
  // indicating its type.
  virtual Technology::Identifier GetDeviceTechnology(
      const std::string& iface_name);
  // Checks the device specified by |iface_name| to see if it's a modem device.
  // This method assumes that |iface_name| has already been determined to be
  // using the cdc_ether / cdc_ncm driver.
  bool IsCdcEthernetModemDevice(const std::string& iface_name);
  // Returns true if |base_dir| has a subdirectory named |subdir|.
  // |subdir| can be an immediate subdirectory of |base_dir| or can be
  // several levels deep.
  static bool HasSubdir(const base::FilePath& base_dir,
                        const base::FilePath& subdir);

  // Returns true and sets |link_name| to the interface name contained
  // in |msg| if one is provided.  Returns false otherwise.
  bool GetLinkNameFromMessage(const RTNLMessage& msg, std::string* link_name);

  // Returns true if |msg| pertains to a blacklisted device whose link name
  // is now different from the name it was assigned before.
  bool IsRenamedBlacklistedDevice(const RTNLMessage& msg);

  void AddLinkMsgHandler(const RTNLMessage& msg);
  void DelLinkMsgHandler(const RTNLMessage& msg);
  void LinkMsgHandler(const RTNLMessage& msg);
  void AddressMsgHandler(const RTNLMessage& msg);
  void RdnssMsgHandler(const RTNLMessage& msg);

  const Info* GetInfo(int interface_index) const;
  void RemoveInfo(int interface_index);
  void DelayDeviceCreation(int interface_index);
  void DelayedDeviceCreationTask();
  void RetrieveLinkStatistics(int interface_index, const RTNLMessage& msg);
  void RequestLinkStatistics();

#if !defined(DISABLE_WIFI)
  // Use nl80211 to get information on |interface_index|.
  void GetWiFiInterfaceInfo(int interface_index);
  void OnWiFiInterfaceInfoReceived(const Nl80211Message& message);
#endif  // DISABLE_WIFI

  void set_sockets(Sockets* sockets) { sockets_.reset(sockets); }

  ControlInterface* control_interface_;
  EventDispatcher* dispatcher_;
  Metrics* metrics_;
  Manager* manager_;

  std::map<int, Info> infos_;  // Maps interface index to Info.
  std::map<std::string, int> indices_;  // Maps interface name to index.

  std::unique_ptr<RTNLListener> link_listener_;
  std::unique_ptr<RTNLListener> address_listener_;
  std::unique_ptr<RTNLListener> rdnss_listener_;
  std::set<std::string> black_list_;
  base::FilePath device_info_root_;

  // Keep track of devices that require a delayed call to CreateDevice().
  base::CancelableClosure delayed_devices_callback_;
  std::set<int> delayed_devices_;

  // Maintain a callback for the periodic link statistics poll task.
  base::CancelableClosure request_link_statistics_callback_;

  // Cache copy of singleton pointers.
  RoutingTable* routing_table_;
  RTNLHandler* rtnl_handler_;
#if !defined(DISABLE_WIFI)
  NetlinkManager* netlink_manager_;
#endif  // DISABLE_WIFI

  // A member of the class so that a mock can be injected for testing.
  std::unique_ptr<Sockets> sockets_;

  Time* time_;

  DISALLOW_COPY_AND_ASSIGN(DeviceInfo);
};

}  // namespace shill

#endif  // SHILL_DEVICE_INFO_H_
