// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/base/device_monitor_win.h"

#include <dbt.h>
#include <windows.h>

#include <map>
#include <memory>

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/win/message_window.h"

namespace device {

class DeviceMonitorMessageWindow;

namespace {

const base::char16 kWindowClassName[] =
    STRING16_LITERAL("DeviceMonitorMessageWindow");
DeviceMonitorMessageWindow* g_message_window;

// Provides basic comparability for GUIDs so that they can be used as keys to an
// STL map.
struct CompareGUID {
  bool operator()(const GUID& a, const GUID& b) const {
    return memcmp(&a, &b, sizeof a) < 0;
  }
};
}

// This singleton class manages a shared message window for all registered
// device notification observers. It vends one instance of DeviceManagerWin for
// each unique GUID it sees.
class DeviceMonitorMessageWindow {
 public:
  static DeviceMonitorMessageWindow* GetInstance() {
    if (!g_message_window) {
      g_message_window = new DeviceMonitorMessageWindow();
      if (g_message_window->Init()) {
        base::AtExitManager::RegisterTask(
            base::Bind(&base::DeletePointer<DeviceMonitorMessageWindow>,
                       base::Unretained(g_message_window)));
      } else {
        delete g_message_window;
        g_message_window = nullptr;
      }
    }
    return g_message_window;
  }

  DeviceMonitorWin* GetForDeviceInterface(const GUID& device_interface) {
    std::unique_ptr<DeviceMonitorWin>& device_monitor =
        device_monitors_[device_interface];
    if (!device_monitor) {
      device_monitor.reset(new DeviceMonitorWin());
    }
    return device_monitor.get();
  }

  DeviceMonitorWin* GetForAllInterfaces() { return &all_device_monitor_; }

 private:
  friend void base::DeletePointer<DeviceMonitorMessageWindow>(
      DeviceMonitorMessageWindow* message_window);

  DeviceMonitorMessageWindow() {}

  ~DeviceMonitorMessageWindow() {
    if (notify_handle_) {
      UnregisterDeviceNotification(notify_handle_);
    }
  }

  bool Init() {
    window_.reset(new base::win::MessageWindow());
    if (!window_->CreateNamed(
            base::Bind(&DeviceMonitorMessageWindow::HandleMessage,
                       base::Unretained(this)),
            base::string16(kWindowClassName))) {
      LOG(ERROR) << "Failed to create message window: " << kWindowClassName;
      return false;
    }

    DEV_BROADCAST_DEVICEINTERFACE db = {sizeof(DEV_BROADCAST_DEVICEINTERFACE),
                                        DBT_DEVTYP_DEVICEINTERFACE};
    notify_handle_ = RegisterDeviceNotification(
        window_->hwnd(), &db,
        DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
    if (!notify_handle_) {
      PLOG(ERROR) << "Failed to register for device notifications";
      return false;
    }

    return true;
  }

  bool HandleMessage(UINT message,
                     WPARAM wparam,
                     LPARAM lparam,
                     LRESULT* result) {
    if (message == WM_DEVICECHANGE &&
        (wparam == DBT_DEVICEARRIVAL || wparam == DBT_DEVICEREMOVECOMPLETE)) {
      DEV_BROADCAST_HDR* hdr = reinterpret_cast<DEV_BROADCAST_HDR*>(lparam);
      if (hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
        return false;

      DEV_BROADCAST_DEVICEINTERFACE* db =
          reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(hdr);

      DeviceMonitorWin* device_monitor = nullptr;
      const auto& map_entry = device_monitors_.find(db->dbcc_classguid);
      if (map_entry != device_monitors_.end())
        device_monitor = map_entry->second.get();

      std::string device_path(base::SysWideToUTF8(db->dbcc_name));
      DCHECK(base::IsStringASCII(device_path));
      device_path = base::ToLowerASCII(device_path);

      if (wparam == DBT_DEVICEARRIVAL) {
        if (device_monitor) {
          device_monitor->NotifyDeviceAdded(db->dbcc_classguid, device_path);
        }
        all_device_monitor_.NotifyDeviceAdded(db->dbcc_classguid, device_path);
      } else if (wparam == DBT_DEVICEREMOVECOMPLETE) {
        if (device_monitor) {
          device_monitor->NotifyDeviceRemoved(db->dbcc_classguid, device_path);
        }
        all_device_monitor_.NotifyDeviceRemoved(db->dbcc_classguid,
                                                device_path);
      }
      *result = NULL;
      return true;
    }
    return false;
  }

  std::map<GUID, std::unique_ptr<DeviceMonitorWin>, CompareGUID>
      device_monitors_;
  DeviceMonitorWin all_device_monitor_;
  std::unique_ptr<base::win::MessageWindow> window_;
  HDEVNOTIFY notify_handle_ = NULL;

  DISALLOW_COPY_AND_ASSIGN(DeviceMonitorMessageWindow);
};

void DeviceMonitorWin::Observer::OnDeviceAdded(const GUID& class_guid,
                                               const std::string& device_path) {
}

void DeviceMonitorWin::Observer::OnDeviceRemoved(
    const GUID& class_guid,
    const std::string& device_path) {}

// static
DeviceMonitorWin* DeviceMonitorWin::GetForDeviceInterface(
    const GUID& device_interface) {
  DeviceMonitorMessageWindow* message_window =
      DeviceMonitorMessageWindow::GetInstance();
  if (message_window) {
    return message_window->GetForDeviceInterface(device_interface);
  }
  return nullptr;
}

// static
DeviceMonitorWin* DeviceMonitorWin::GetForAllInterfaces() {
  DeviceMonitorMessageWindow* message_window =
      DeviceMonitorMessageWindow::GetInstance();
  if (message_window) {
    return message_window->GetForAllInterfaces();
  }
  return nullptr;
}

DeviceMonitorWin::~DeviceMonitorWin() {}

void DeviceMonitorWin::AddObserver(Observer* observer) {
  observer_list_.AddObserver(observer);
}

void DeviceMonitorWin::RemoveObserver(Observer* observer) {
  observer_list_.RemoveObserver(observer);
}

DeviceMonitorWin::DeviceMonitorWin() {}

void DeviceMonitorWin::NotifyDeviceAdded(const GUID& class_guid,
                                         const std::string& device_path) {
  for (auto& observer : observer_list_)
    observer.OnDeviceAdded(class_guid, device_path);
}

void DeviceMonitorWin::NotifyDeviceRemoved(const GUID& class_guid,
                                           const std::string& device_path) {
  for (auto& observer : observer_list_)
    observer.OnDeviceRemoved(class_guid, device_path);
}

}  // namespace device
