// Copyright 2020 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 TYPECD_UDEV_MONITOR_H_
#define TYPECD_UDEV_MONITOR_H_

#include <libudev.h>

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

#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_path.h>
#include <base/observer_list.h>
#include <base/observer_list_types.h>
#include <brillo/udev/mock_udev.h>
#include <gtest/gtest_prod.h>

namespace typecd {

constexpr char kTypeCSubsystem[] = "typec";
constexpr char kUdevMonitorName[] = "udev";

// Class to monitor udev events on the Type C subsystem and inform other
// objects / classes of these events.
class UdevMonitor {
 public:
  UdevMonitor() = default;

  // Create a Udev device for enumeration and monitoring.
  bool InitUdev();

  // Enumerate all existing events/devices, and send the appropriate
  // notifications to other classes.
  bool ScanDevices();

  // Start monitoring udev for typec events.
  bool BeginMonitoring();

  class Observer : public base::CheckedObserver {
   public:
    virtual ~Observer() {}
    // Callback that is executed when a port is connected or disconnected.
    //
    // The |path| argument refers to the sysfs device path of the port.
    // The |port_num| argmnet refers to the port's index number.
    // The |added| argument is set to true if the port was added, and false
    // otherwise.
    virtual void OnPortAddedOrRemoved(const base::FilePath& path,
                                      int port_num,
                                      bool added) = 0;

    // Callback that is executed when a port partner is connected or
    // disconnected.
    //
    // The |path| argument refers to the sysfs device path of the port partner.
    // The |port_num| argument refers to the port's index number.
    // The |added| argument is set to true if the partner was added, and false
    // otherwise.
    virtual void OnPartnerAddedOrRemoved(const base::FilePath& path,
                                         int port_num,
                                         bool added) = 0;

    // Callback that is executed when a port partner alt mode is registered or
    // removed.
    //
    // The |path| argument refers to the sysfs device path of the partner alt
    // mode. The |port_num| argmnet refers to the port's index number. The
    // |added| argument is set to true if the alt mode was added, and false
    // otherwise.
    virtual void OnPartnerAltModeAddedOrRemoved(const base::FilePath& path,
                                                int port_num,
                                                bool added) = 0;

    // Callback that is executed when a port cable is connected or
    // disconnected.
    //
    // The |path| argument refers to the sysfs device path of the port cable.
    // The |port_num| argument refers to the port's index number.
    // The |added| argument is set to true if the cable was added, and false
    // otherwise.
    virtual void OnCableAddedOrRemoved(const base::FilePath& path,
                                       int port_num,
                                       bool added) = 0;

    // Callback that is executed when a cable plug (SOP') device is registered.
    //
    // The |path| argument refers to the sysfs device path of the cable plug
    // (SOP'). The |port_num| argument refers to the port's index number.
    virtual void OnCablePlugAdded(const base::FilePath& path, int port_num) = 0;

    // Callback that is executed when a cable (SOP') alternate mode is
    // registered.
    //
    // The |path| argument refers to the sysfs device path of the cable (SOP')
    // alternate mode. The |port_num| argument refers to the port's index
    // number.
    virtual void OnCableAltModeAdded(const base::FilePath& path,
                                     int port_num) = 0;

    // Callback that is executed when a partner "change" event is received.
    //
    // The |port_num| argument refers to the port's index number.
    virtual void OnPartnerChanged(int port_num) = 0;
  };

  void AddObserver(Observer* obs);
  void RemoveObserver(Observer* obs);

 private:
  friend class UdevMonitorTest;
  FRIEND_TEST(UdevMonitorTest, TestBasic);
  FRIEND_TEST(UdevMonitorTest, TestHotplug);
  FRIEND_TEST(UdevMonitorTest, TestInvalidPortSyspath);
  FRIEND_TEST(UdevMonitorTest, TestCableAndAltModeAddition);
  FRIEND_TEST(UdevMonitorTest, TestPartnerChanged);

  // Set the |udev_| pointer to a MockUdev device. *Only* used by unit tests.
  void SetUdev(std::unique_ptr<brillo::MockUdev> udev) {
    udev_ = std::move(udev);
  }

  // Handle a udev event which causes a Type C device to be added/removed.
  bool HandleDeviceAddedRemoved(const base::FilePath& path, bool added);

  // Handle a udev "change" event for a Type C device.
  void HandleDeviceChange(const base::FilePath& path);

  // Handle Udev events emanating from |udev_monitor_watcher_|.
  void HandleUdevEvent();

  std::unique_ptr<brillo::Udev> udev_;
  std::unique_ptr<brillo::UdevMonitor> udev_monitor_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller>
      udev_monitor_watcher_;
  base::ObserverList<Observer> observer_list_;
};

}  // namespace typecd

#endif  // TYPECD_UDEV_MONITOR_H_
