// Copyright (c) 2012 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.

#ifndef DEVICE_BLUETOOTH_BLUETOOTH_TASK_MANAGER_WIN_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_TASK_MANAGER_WIN_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/observer_list.h"
#include "base/win/scoped_handle.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_low_energy_win.h"

namespace base {

class SequencedTaskRunner;
class SequencedWorkerPool;

}  // namespace base

namespace device {

// Manages the blocking Bluetooth tasks using |SequencedWorkerPool|. It runs
// bluetooth tasks using |SequencedWorkerPool| and informs its observers of
// bluetooth adapter state changes and any other bluetooth device inquiry
// result.
//
// It delegates the blocking Windows API calls to |bluetooth_task_runner_|'s
// message loop, and receives responses via methods like OnAdapterStateChanged
// posted to UI thread.
class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
    : public base::RefCountedThreadSafe<BluetoothTaskManagerWin> {
 public:
  struct DEVICE_BLUETOOTH_EXPORT AdapterState {
    AdapterState();
    ~AdapterState();
    std::string name;
    std::string address;
    bool powered;
  };

  struct DEVICE_BLUETOOTH_EXPORT ServiceRecordState {
    ServiceRecordState();
    ~ServiceRecordState();
    // Properties common to Bluetooth Classic and LE devices.
    std::string name;
    // Properties specific to Bluetooth Classic devices.
    std::vector<uint8_t> sdp_bytes;
    // Properties specific to Bluetooth LE devices.
    BluetoothUUID gatt_uuid;
    uint16_t attribute_handle;
    // GATT service device path.
    // Note: Operation of the included characteristics and descriptors of this
    // service must use service device path instead of resident device device
    // path.
    base::FilePath path;
  };

  struct DEVICE_BLUETOOTH_EXPORT DeviceState {
    DeviceState();
    ~DeviceState();

    bool is_bluetooth_classic() const { return path.empty(); }

    // Properties common to Bluetooth Classic and LE devices.
    std::string address;  // This uniquely identifies the device.
    std::string name;     // Friendly name
    bool visible;
    bool connected;
    bool authenticated;
    ScopedVector<ServiceRecordState> service_record_states;
    // Properties specific to Bluetooth Classic devices.
    uint32_t bluetooth_class;
    // Properties specific to Bluetooth LE devices.
    base::FilePath path;
  };

  class DEVICE_BLUETOOTH_EXPORT Observer {
   public:
     virtual ~Observer() {}

     virtual void AdapterStateChanged(const AdapterState& state) {}
     virtual void DiscoveryStarted(bool success) {}
     virtual void DiscoveryStopped() {}
     // Called when the adapter has just been polled for the list of *all* known
     // devices. This includes devices previously paired, devices paired using
     // the underlying Operating System UI, and devices discovered recently due
     // to an active discovery session. Note that for a given device (address),
     // the associated state can change over time. For example, during a
     // discovery session, the "friendly" name may initially be "unknown" before
     // the actual name is retrieved in subsequent poll events.
     virtual void DevicesPolled(const ScopedVector<DeviceState>& devices) {}
  };

  explicit BluetoothTaskManagerWin(
      scoped_refptr<base::SequencedTaskRunner> ui_task_runner);

  static BluetoothUUID BluetoothLowEnergyUuidToBluetoothUuid(
      const BTH_LE_UUID& bth_le_uuid);

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

  void Initialize();
  void InitializeWithBluetoothTaskRunner(
      scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner);
  void Shutdown();

  void PostSetPoweredBluetoothTask(
      bool powered,
      const base::Closure& callback,
      const BluetoothAdapter::ErrorCallback& error_callback);
  void PostStartDiscoveryTask();
  void PostStopDiscoveryTask();

  // Callbacks of asynchronous operations of GATT service.
  typedef base::Callback<void(HRESULT)> HResultCallback;
  typedef base::Callback<
      void(std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC>, uint16_t, HRESULT)>
      GetGattIncludedCharacteristicsCallback;
  typedef base::Callback<
      void(std::unique_ptr<BTH_LE_GATT_DESCRIPTOR>, uint16_t, HRESULT)>
      GetGattIncludedDescriptorsCallback;
  typedef base::Callback<void(std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE>,
                              HRESULT)>
      ReadGattCharacteristicValueCallback;
  typedef base::Callback<void(std::unique_ptr<std::vector<uint8_t>>)>
      GattCharacteristicValueChangedCallback;
  typedef base::Callback<void(PVOID, HRESULT)> GattEventRegistrationCallback;

  // Get all included characteristics of a given service. The service is
  // uniquely identified by its |uuid| and |attribute_handle| with service
  // device |service_path|. The result is returned asynchronously through
  // |callback|.
  void PostGetGattIncludedCharacteristics(
      const base::FilePath& service_path,
      const BluetoothUUID& uuid,
      uint16_t attribute_handle,
      const GetGattIncludedCharacteristicsCallback& callback);

  // Get all included descriptors of a given |characterisitc| in service
  // with |service_path|. The result is returned asynchronously through
  // |callback|.
  void PostGetGattIncludedDescriptors(
      const base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      const GetGattIncludedDescriptorsCallback& callback);

  // Post read the value of a given |characteristic| in service with
  // |service_path|. The result is returned asynchronously through |callback|.
  void PostReadGattCharacteristicValue(
      const base::FilePath& device_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      const ReadGattCharacteristicValueCallback& callback);

  // Post write the value of a given |characteristic| in service with
  // |service_path| to |new_value|. The operation result is returned
  // asynchronously through |callback|.
  void PostWriteGattCharacteristicValue(
      const base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      const std::vector<uint8_t>& new_value,
      const HResultCallback& callback);

  // Post a task to register to receive value changed notifications from
  // |characteristic| in service with |service_path|. |ccc_descriptor| is the
  // Client Characteristic Configuration descriptor. |registered_callback| is
  // the function to be invoked if the event occured. The operation result is
  // returned asynchronously through |callback|.
  void PostRegisterGattCharacteristicValueChangedEvent(
      const base::FilePath& service_path,
      const PBTH_LE_GATT_CHARACTERISTIC characteristic,
      const PBTH_LE_GATT_DESCRIPTOR ccc_descriptor,
      const GattEventRegistrationCallback& callback,
      const GattCharacteristicValueChangedCallback& registered_callback);

  // Post a task to unregister from value change notifications. |event_handle|
  // was returned by PostRegisterGattCharacteristicValueChangedEvent.
  void PostUnregisterGattCharacteristicValueChangedEvent(PVOID event_handle);

 private:
  friend class base::RefCountedThreadSafe<BluetoothTaskManagerWin>;
  friend class BluetoothTaskManagerWinTest;

  static const int kPollIntervalMs;

  virtual ~BluetoothTaskManagerWin();

  // Logs Win32 errors occurring during polling on the worker thread. The method
  // may discard messages to avoid logging being too verbose.
  void LogPollingError(const char* message, int win32_error);

  // Notify all Observers of updated AdapterState. Should only be called on the
  // UI thread.
  void OnAdapterStateChanged(const AdapterState* state);
  void OnDiscoveryStarted(bool success);
  void OnDiscoveryStopped();
  void OnDevicesPolled(const ScopedVector<DeviceState>* devices);

  // Called on BluetoothTaskRunner.
  void StartPolling();
  void PollAdapter();
  void PostAdapterStateToUi();
  void SetPowered(bool powered,
                  const base::Closure& callback,
                  const BluetoothAdapter::ErrorCallback& error_callback);

  // Starts discovery. Once the discovery starts, it issues a discovery inquiry
  // with a short timeout, then issues more inquiries with greater timeout
  // values. The discovery finishes when StopDiscovery() is called or timeout
  // has reached its maximum value.
  void StartDiscovery();
  void StopDiscovery();

  // Issues a device inquiry that runs for |timeout_multiplier| * 1.28 seconds.
  // This posts itself again with |timeout_multiplier| + 1 until
  // |timeout_multiplier| reaches the maximum value or stop discovery call is
  // received.
  void DiscoverDevices(int timeout_multiplier);

  // Fetch already known device information. Similar to |StartDiscovery|, except
  // this function does not issue a discovery inquiry. Instead it gets the
  // device info cached in the adapter.
  void GetKnownDevices();

  // Looks for Bluetooth Classic and Low Energy devices, as well as the services
  // exposed by those devices.
  bool SearchDevices(int timeout_multiplier,
                     bool search_cached_devices_only,
                     ScopedVector<DeviceState>* device_list);

  // Sends a device search API call to the adapter to look for Bluetooth Classic
  // devices.
  bool SearchClassicDevices(int timeout_multiplier,
                            bool search_cached_devices_only,
                            ScopedVector<DeviceState>* device_list);

  // Enumerate Bluetooth Low Energy devices.
  bool SearchLowEnergyDevices(ScopedVector<DeviceState>* device_list);

  // Discover services for the devices in |device_list|.
  bool DiscoverServices(ScopedVector<DeviceState>* device_list,
                        bool search_cached_services_only);

  // Discover Bluetooth Classic services for the given |device_address|.
  bool DiscoverClassicDeviceServices(
      const std::string& device_address,
      const GUID& protocol_uuid,
      bool search_cached_services_only,
      ScopedVector<ServiceRecordState>* service_record_states);

  // Discover Bluetooth Classic services for the given |device_address|.
  // Returns a Win32 error code.
  int DiscoverClassicDeviceServicesWorker(
      const std::string& device_address,
      const GUID& protocol_uuid,
      bool search_cached_services_only,
      ScopedVector<ServiceRecordState>* service_record_states);

  // Discover Bluetooth Low Energy services for the given |device_path|.
  bool DiscoverLowEnergyDeviceServices(
      const base::FilePath& device_path,
      ScopedVector<ServiceRecordState>* service_record_states);

  // Search for device paths of the GATT services in |*service_record_states|
  // from |device_address|.
  bool SearchForGattServiceDevicePaths(
      const std::string device_address,
      ScopedVector<ServiceRecordState>* service_record_states);

  // GATT service related functions.
  void GetGattIncludedCharacteristics(
      base::FilePath device_path,
      BluetoothUUID uuid,
      uint16_t attribute_handle,
      const GetGattIncludedCharacteristicsCallback& callback);
  void GetGattIncludedDescriptors(
      base::FilePath service_path,
      BTH_LE_GATT_CHARACTERISTIC characteristic,
      const GetGattIncludedDescriptorsCallback& callback);
  void ReadGattCharacteristicValue(
      base::FilePath device_path,
      BTH_LE_GATT_CHARACTERISTIC characteristic,
      const ReadGattCharacteristicValueCallback& callback);
  void WriteGattCharacteristicValue(base::FilePath service_path,
                                    BTH_LE_GATT_CHARACTERISTIC characteristic,
                                    std::vector<uint8_t> new_value,
                                    const HResultCallback& callback);
  void RegisterGattCharacteristicValueChangedEvent(
      base::FilePath service_path,
      BTH_LE_GATT_CHARACTERISTIC characteristic,
      BTH_LE_GATT_DESCRIPTOR ccc_descriptor,
      const GattEventRegistrationCallback& callback,
      const GattCharacteristicValueChangedCallback& registered_callback);
  void UnregisterGattCharacteristicValueChangedEvent(PVOID event_handle);

  // UI task runner reference.
  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;

  scoped_refptr<base::SequencedWorkerPool> worker_pool_;
  scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner_;

  // List of observers interested in event notifications.
  base::ObserverList<Observer> observers_;

  // Weak reference of the adapter handle, let BluetoothClassicWrapper handle
  // the close of |adapter_handle_|.
  HANDLE adapter_handle_;

  // indicates whether the adapter is in discovery mode or not.
  bool discovering_;

  // Use for discarding too many log messages.
  base::TimeTicks current_logging_batch_ticks_;
  int current_logging_batch_count_;

  DISALLOW_COPY_AND_ASSIGN(BluetoothTaskManagerWin);
};

}  // namespace device

#endif  // DEVICE_BLUETOOTH_BLUETOOTH_TASK_MANAGER_WIN_H_
