//
//  Copyright (C) 2015 Google, Inc.
//
//  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.
//

#pragma once

#include <atomic>
#include <functional>
#include <map>
#include <mutex>

#include <base/macros.h>

#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/advertise_data.h"
#include "service/common/bluetooth/advertise_settings.h"
#include "service/common/bluetooth/low_energy_constants.h"
#include "service/common/bluetooth/scan_filter.h"
#include "service/common/bluetooth/scan_result.h"
#include "service/common/bluetooth/scan_settings.h"
#include "service/common/bluetooth/uuid.h"
#include "service/hal/bluetooth_gatt_interface.h"

namespace bluetooth {

class Adapter;

// A LowEnergyAdvertiser represents an application's handle to perform various
// Bluetooth Low Energy GAP operations. Instances cannot be created directly and
// should be obtained through the factory.
class LowEnergyAdvertiser : public BluetoothInstance {
 public:
  // The destructor automatically unregisters this client instance from the
  // stack.
  ~LowEnergyAdvertiser() override;

  // Callback type used to return the result of asynchronous operations below.
  using StatusCallback = std::function<void(BLEStatus)>;

  // Starts advertising based on the given advertising and scan response
  // data and the provided |settings|. Reports the result of the operation in
  // |callback|. Return true on success, false otherwise. Please see logs for
  // details in case of error.
  bool StartAdvertising(const AdvertiseSettings& settings,
                        const AdvertiseData& advertise_data,
                        const AdvertiseData& scan_response,
                        const StatusCallback& callback);

  // Stops advertising if it was already started. Reports the result of the
  // operation in |callback|.
  bool StopAdvertising(const StatusCallback& callback);

  // Returns true if advertising has been started.
  bool IsAdvertisingStarted() const;

  // Returns the state of pending advertising operations.
  bool IsStartingAdvertising() const;
  bool IsStoppingAdvertising() const;

  // Returns the current advertising settings.
  const AdvertiseSettings& advertise_settings() const {
    return advertise_settings_;
  }

  // BluetoothClientInstace overrides:
  const UUID& GetAppIdentifier() const override;
  int GetInstanceId() const override;

 private:
  friend class LowEnergyAdvertiserFactory;

  // Constructor shouldn't be called directly as instances are meant to be
  // obtained from the factory.
  LowEnergyAdvertiser(const UUID& uuid, int advertiser_id);

  // BluetoothGattInterface::AdvertiserObserver overrides:
  void SetDataCallback(uint8_t advertiser_id, uint8_t status);
  void SetParamsCallback(uint8_t advertiser_id, uint8_t status);
  void EnableCallback(bool enable, uint8_t advertiser_id, uint8_t status);

  // Calls and clears the pending callbacks.
  void InvokeAndClearStartCallback(BLEStatus status);
  void InvokeAndClearStopCallback(BLEStatus status);

  // See getters above for documentation.
  UUID app_identifier_;
  int advertiser_id_;

  // Protects advertising-related members below.
  std::mutex adv_fields_lock_;

  // Latest advertising settings.
  AdvertiseSettings advertise_settings_;

  std::atomic_bool adv_started_;
  std::unique_ptr<StatusCallback> adv_start_callback_;
  std::unique_ptr<StatusCallback> adv_stop_callback_;

  DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiser);
};

// LowEnergyAdvertiserFactory is used to register and obtain a per-application
// LowEnergyAdvertiser instance. Users should call RegisterInstance to obtain
// their
// own unique LowEnergyAdvertiser instance that has been registered with the
// Bluetooth stack.
class LowEnergyAdvertiserFactory : public BluetoothInstanceFactory {
 public:
  // Don't construct/destruct directly except in tests. Instead, obtain a handle
  // from an Adapter instance.
  explicit LowEnergyAdvertiserFactory();
  ~LowEnergyAdvertiserFactory() override;

  // BluetoothInstanceFactory override:
  bool RegisterInstance(const UUID& app_uuid,
                        const RegisterCallback& callback) override;

 private:
  friend class LowEnergyAdvertiser;

  // BluetoothGattInterface::AdvertiserObserver overrides:
  void RegisterAdvertiserCallback(const RegisterCallback& callback,
                                  const UUID& app_uuid, uint8_t advertiser_id,
                                  uint8_t status);

  // Map of pending calls to register.
  std::mutex pending_calls_lock_;
  std::unordered_set<UUID> pending_calls_;

  DISALLOW_COPY_AND_ASSIGN(LowEnergyAdvertiserFactory);
};

}  // namespace bluetooth
