/*
 * Copyright 2018 The Android Open Source Project
 *
 * 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 <base/bind.h>
#include <base/memory/weak_ptr.h>
#include <map>
#include <memory>

#include "avrcp_internal.h"
#include "avrcp_packet.h"
#include "device.h"
#include "packet.h"
#include "raw_address.h"

namespace bluetooth {
namespace avrcp {

// TODO: Remove the singleton design structure for this class.
// AvrcpTargetService is already a singleton and can manage the lifetime of this
// object. multiple singleton objects can lead to code that is hard to test and
// have hard to debug lifetimes.

// TODO (apanicke): Use a device factory instead of just the constructor in
// order to create device objects. This will allow us to create specific device
// classes that can provide interop fixes for certain badly behaving devices.

/**
 * ConnectionHandler handles SDP, connecting to remote AVRCP devices
 * and multiplexing/delivering messages to devices.
 */
class ConnectionHandler {
 public:
  /**
   * This callback is used to return a new device after a connection attempt.
   * A reference to the new Avrcp device is located in the shared_ptr.
   * If there was an issue during connection the pointer value will be null.
   */
  using ConnectionCallback = base::Callback<void(std::shared_ptr<Device>)>;

  /**
   * Initializes the singleton instance and sets up SDP. Also Opens the
   * AVRCP Acceptor to receive connection requests from a remote device.
   *
   * Params:
   * callback - A callback that gets called any time a new AVRCP Device
   *            is connected. Will return nullpointer if a device fails
   *            to connect via ConnectDevice();
   *
   * TODO: Add message loop to determine which thread events are posted to
   */
  static bool Initialize(const ConnectionCallback& callback,
                         AvrcpInterface* avrcp, SdpInterface* sdp,
                         VolumeInterface* vol);

  /**
   * Clears the singleton and tears down SDP
   */
  static bool CleanUp();

  /**
   * Get the singleton instance of Connection Handler
   */
  static ConnectionHandler* Get();

  /**
   * Attempt to connect AVRCP on a device. The callback will be called with
   * either a smart pointer pointing to the connected AVRCP device or null
   * if the connection failed.
   *
   * The order of operations for this function is as follows.
   *   1. Perform SDP on remote device
   *   2. Connect the AVCTP Channel
   *   2. (Optional) If supported connect the AVCTP Browse channel
   *   4. Call the provided callback with the new
   *
   * Params:
   * bdaddr - Bluetooth address of device to connect to
   * callback - The function that gets called when a connection succeeds or
   *            fails. The pointer being cleared implies that the connection
   *            failed.
   *
   * Returns:
   * true if the connection attempt starts, false if there are no resources to
   * connect AVRCP
   */
  virtual bool ConnectDevice(const RawAddress& bdaddr);

  /**
   * Disconnects AVRCP from a device that was successfully connected too using
   * ConnectionHandler::ConnectDevice
   *
   * Returns:
   * true if the AVRCP was successfully disconnected for the device or false
   * if the device was already disconnected or in an invalid state
   */
  virtual bool DisconnectDevice(const RawAddress& bdaddr);

  virtual std::vector<std::shared_ptr<Device>> GetListOfDevices() const;

  /**
   * Provide a custom ConnectionHandler that will be returned by Get().
   * Initialize and CleanUp should not be called as the owner of the handler
   * determines its lifetime.
   */
  static void InitForTesting(ConnectionHandler* handler);

 private:
  AvrcpInterface* avrc_;
  SdpInterface* sdp_;
  VolumeInterface* vol_;

  ConnectionCallback connection_cb_;

  std::map<uint8_t, std::shared_ptr<Device>> device_map_;
  // TODO (apanicke): Replace the features with a class that has individual
  // fields.
  std::map<RawAddress, uint16_t> feature_map_;

  static ConnectionHandler* instance_;

  using SdpCallback = base::Callback<void(uint16_t status, uint16_t version,
                                          uint16_t features)>;
  virtual bool SdpLookup(const RawAddress& bdaddr, SdpCallback cb);
  void SdpCb(const RawAddress& bdaddr, SdpCallback cb,
             tSDP_DISCOVERY_DB* disc_db, uint16_t status);

  virtual bool AvrcpConnect(bool initiator, const RawAddress& bdaddr);

  // Callbacks when connecting to a device
  void InitiatorControlCb(uint8_t handle, uint8_t event, uint16_t result,
                          const RawAddress* peer_addr);
  void AcceptorControlCb(uint8_t handle, uint8_t event, uint16_t result,
                         const RawAddress* peer_addr);
  void MessageCb(uint8_t handle, uint8_t label, uint8_t opcode,
                 tAVRC_MSG* p_msg);

  ConnectionHandler() : weak_ptr_factory_(this){};
  virtual ~ConnectionHandler() = default;

  // Callback for when sending a response to a device
  void SendMessage(uint8_t handle, uint8_t label, bool browse,
                   std::unique_ptr<::bluetooth::PacketBuilder> message);

  base::WeakPtrFactory<ConnectionHandler> weak_ptr_factory_;
  DISALLOW_COPY_AND_ASSIGN(ConnectionHandler);
};

}  // namespace avrcp
}  // namespace bluetooth
