// Copyright 2018 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_DEVICE_INFO_H_
#define SHILL_DEVICE_INFO_H_

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

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/files/file_path.h>
#include <base/memory/weak_ptr.h>
#include <base/optional.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>

#include "shill/net/byte_string.h"
#include "shill/net/ip_address.h"
#include "shill/net/shill_time.h"
#include "shill/net/sockets.h"
#include "shill/refptr_types.h"
#include "shill/technology.h"

#if !defined(DISABLE_CELLULAR)
#include "shill/cellular/cellular.h"
#endif

namespace shill {

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

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

#if !defined(DISABLE_CELLULAR)
class Modem;
#endif

class DeviceInfo {
 public:
  // Type of callback function triggered when an RTNL link add event occurs.
  // First parameter is link name and second parameter interface index.
  using LinkReadyCallback = base::OnceCallback<void(const std::string&, int)>;

  explicit DeviceInfo(Manager* manager);
  DeviceInfo(const DeviceInfo&) = delete;
  DeviceInfo& operator=(const DeviceInfo&) = delete;

  virtual ~DeviceInfo();

  virtual void BlockDevice(const std::string& device_name);
  virtual void AllowDevice(const std::string& device_name);
  virtual bool IsDeviceBlocked(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);

  // Deregister the Device instance (if any) from interested parties like
  // Manager and Metrics, and remove the Info corresponding to this
  // interface. No-op if there is no Info for this interface index.
  void DeregisterDevice(int interface_index);

  virtual DeviceRefPtr GetDevice(int interface_index) const;

#if !defined(DISABLE_CELLULAR)
  // Returns a valid Celluar Device as follows:
  // 1. If no device matching |interface_index| exists, a new device is created.
  // 2. If a matching device exists and all key |modem| properties match
  //    (see implementation for details), the existing device is returned.
  // 3. If a matching Device exists but key |modem| properties do not match,
  //    the existing device is deregistered and a new device is created.
  // Once a device is found or created, CreateCapability is called for the
  // device to create a CellularCapability for |modem|.
  // NOTE: |mac_address| and modem->path are not required to match. If a
  // matching device is found, the mac address and modem path will be updated.
  virtual CellularRefPtr GetCellularDevice(int interface_index,
                                           const std::string& mac_address,
                                           Modem* modem);
#endif

  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 std::vector<IPAddress> GetAddresses(int interface_index) 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 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);

  virtual bool CreateTunnelInterface(LinkReadyCallback callback);
  virtual int OpenTunnelInterface(const std::string& interface_name) const;
  virtual bool DeleteInterface(int interface_index) const;
  virtual void AddVirtualInterfaceReadyCallback(
      const std::string& interface_name, LinkReadyCallback callback);

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

  // Gets the real user ID of the given |user_name| and returns it via |uid|.
  // Returns true on success.
  virtual bool GetUserId(const std::string& user_name, uid_t* uid);

  // Notifies this object that patchpanel::Client is ready in Manager. Registers
  // neighbor connected events handler via manager_->patchpanel_client().
  void OnPatchpanelClientReady();

  Manager* manager() const { return manager_; }

 private:
  friend class DeviceInfoDelayedCreationTest;
  friend class DeviceInfoMockedGetUserId;
  friend class DeviceInfoTechnologyTest;
  friend class DeviceInfoTest;
  FRIEND_TEST(CellularTest, StartLinked);
  FRIEND_TEST(DeviceInfoTest, DeviceRemovedEvent);
  FRIEND_TEST(DeviceInfoTest, GetUninitializedTechnologies);
  FRIEND_TEST(DeviceInfoTest, HasSubdir);           // For HasSubdir.
  FRIEND_TEST(DeviceInfoTest, IPv6AddressChanged);  // For infos_.
  FRIEND_TEST(DeviceInfoTest, StartStop);
  FRIEND_TEST(DeviceInfoTest, IPv6DnsServerAddressesChanged);  // For infos_.
  FRIEND_TEST(DeviceInfoMockedGetUserId,
              AddRemoveAllowedInterface);  // For rtnl_handler_, routing_table_.
  FRIEND_TEST(DeviceInfoTest, CreateDeviceTunnel);  // For pending_links_.

  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;
  };

  struct Info {
    Info();

    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 a link add RTNL message has been received for
    // this interface. This is used to behave differently for the first link add
    // message received for this interface index; |device| is unsuitable because
    // some interfaces may undergo delayed Device creation.
    bool received_add_link;

    Technology technology;
  };

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

  // Return the ARP type (ARPHRD_* from <net/if_arp.h>) of interface
  // |iface_name|.
  int GetDeviceArpType(const std::string& iface_name);
  // 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 preferred globally scoped IPv6 address for |interface_index|.
  // If no primary IPv6 address exists, return nullptr.
  const IPAddress* GetPrimaryIPv6Address(int interface_index);
  // 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| with RTNL kind |kind|, and return
  // an identifier indicating its type.
  virtual Technology GetDeviceTechnology(
      const std::string& iface_name, const base::Optional<std::string>& kind);
  // 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 blocked device whose link name
  // is now different from the name it was assigned before.
  bool IsRenamedBlockedDevice(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 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);
  void RecordDarkResumeWakeReason(const std::string& wake_reason);
#endif  // DISABLE_WIFI

  // Returns whether a device with name |interface_name| is guest.
  bool IsGuestDevice(const std::string& interface_name);

  void OnNeighborReachabilityEvent(
      const patchpanel::NeighborReachabilityEventSignal& signal);

  void set_sockets_for_test(std::unique_ptr<Sockets> sockets) {
    sockets_ = std::move(sockets);
  }

  Manager* manager_;
  EventDispatcher* dispatcher_ = nullptr;
  Metrics* metrics_ = nullptr;

  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> blocked_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_;

  // Maintain the list of callbacks awaiting link ready event.
  // Used by VPNServices for tunnel (through calling CreateTunnel with
  // callback) and ppp (through direct registering callback).
  // Callback are one-time and will be removed once triggered.
  // Keys of the map are names of the link concerned.
  std::map<std::string, LinkReadyCallback> pending_links_;

  // 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_;
  base::WeakPtrFactory<DeviceInfo> weak_factory_{this};
};

}  // namespace shill

#endif  // SHILL_DEVICE_INFO_H_
