/*
 * 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/cancelable_callback.h>
#include <base/functional/bind.h>

#include <iostream>
#include <memory>
#include <stack>
#include <vector>

#include "avrcp_internal.h"
#include "hardware/avrcp/avrcp.h"
#include "packet/avrcp/avrcp_browse_packet.h"
#include "packet/avrcp/avrcp_packet.h"
#include "packet/avrcp/capabilities_packet.h"
#include "packet/avrcp/change_path.h"
#include "packet/avrcp/get_current_player_application_setting_value.h"
#include "packet/avrcp/get_element_attributes_packet.h"
#include "packet/avrcp/get_folder_items.h"
#include "packet/avrcp/get_item_attributes.h"
#include "packet/avrcp/get_total_number_of_items.h"
#include "packet/avrcp/list_player_application_setting_attributes.h"
#include "packet/avrcp/list_player_application_setting_values.h"
#include "packet/avrcp/play_item.h"
#include "packet/avrcp/register_notification_packet.h"
#include "packet/avrcp/set_addressed_player.h"
#include "packet/avrcp/set_browsed_player.h"
#include "packet/avrcp/set_player_application_setting_value.h"
#include "packet/avrcp/vendor_packet.h"
#include "profile/avrcp/media_id_map.h"
#include "raw_address.h"

namespace bluetooth {
namespace avrcp {

/**
 * A class representing a connection with a remote AVRCP device. It holds all
 * the state and message handling for the device that it represents.
 */
// TODO (apanicke): Once we move over to having the individual message
// responders for Browse and Classic AVRCP Messages move the device around via a
// weak pointer.
class Device {
 public:
  /**
   * Device is friends with Avrcp::ConnectionHandler so that ConnectionHandler
   * can deliver messages to individual devices.
   */
  friend class ConnectionHandler;

  Device(const RawAddress& bdaddr, bool avrcp13_compatibility,
         base::RepeatingCallback<
             void(uint8_t label, bool browse,
                  std::unique_ptr<::bluetooth::PacketBuilder> message)>
             send_msg_cb,
         uint16_t ctrl_mtu, uint16_t browse_mtu);

  Device(const Device&) = delete;
  Device& operator=(const Device&) = delete;

  virtual ~Device() = default;

  /**
   * Gets a weak pointer to this device that is invalidated when the device is
   * disconnected.
   */
  base::WeakPtr<Device> Get();

  const RawAddress& GetAddress() const { return address_; };

  /**
   * Disconnects the AVRCP connection that this device represents.
   */
  bool Disconnect();

  /**
   * Set the status of the BIP obex client
   */
  void SetBipClientStatus(bool connected);

  /**
   * Returns true if the current device has a BIP OBEX client.
   */
  bool HasBipClient() const;

  /**
   * Returns true if the current device is silenced.
   */
  bool IsInSilenceMode() const;

  /**
   * Returns true if the current device is active.
   */
  bool IsActive() const;

  /**
   * Register the interfaces that the device uses to get information. If the
   * Volume Interface is null, then absolute volume is disabled.
   * TODO (apanicke): Add these to the constructor/factory so that each device
   * is created valid and can't be accidentally interacted with when no
   * interfaces are registered.
   */
  void RegisterInterfaces(MediaInterface* interface,
                          A2dpInterface* a2dp_interface,
                          VolumeInterface* volume_interface,
                          PlayerSettingsInterface* player_settings_interface);

  /**
   * Set the maximum size of a AVRCP Browsing Packet. This is done after the
   * connection of the Browsing channel.
   */
  void SetBrowseMtu(uint16_t browse_mtu);

  /**
   * Notify the device that metadata, play_status, and/or queue have updated
   * via a boolean. Each boolean represents whether its respective content has
   * updated.
   */
  virtual void SendMediaUpdate(bool metadata, bool play_status, bool queue);

  /**
   * Notify the device that the available_player, addressed_player, or UIDs
   * have updated via a boolean. Each boolean represents whether its respective
   * content has updated.
   */
  virtual void SendFolderUpdate(bool available_player, bool addressed_player,
                                bool uids);

  // TODO (apanicke): Split the message handlers into two files. One
  // for handling Browse Messages and the other for handling all other
  // messages. This prevents the .cc file from getting bloated like it is
  // now. The Device class will then become a state holder for each message
  // and all the functions in these handler classes can be static since the
  // device will be passed in. The extensions of the Device class can contain
  // any interop handling for specific messages on specific devices.

  void MessageReceived(uint8_t label, std::shared_ptr<Packet> pkt);
  void BrowseMessageReceived(uint8_t label, std::shared_ptr<BrowsePacket> pkt);
  void VendorPacketHandler(uint8_t label, std::shared_ptr<VendorPacket> pkt);

  /********************
   * MESSAGE RESPONSES
   ********************/
  // CURRENT TRACK CHANGED
  virtual void HandleTrackUpdate();
  virtual void TrackChangedNotificationResponse(
      uint8_t label, bool interim, std::string curr_song_id,
      std::vector<SongInfo> song_list);

  // GET CAPABILITY
  virtual void HandleGetCapabilities(
      uint8_t label, const std::shared_ptr<GetCapabilitiesRequest>& pkt);

  // REGISTER NOTIFICATION
  virtual void HandleNotification(
      uint8_t label, const std::shared_ptr<RegisterNotificationRequest>& pkt);

  // PLAY STATUS CHANGED
  virtual void HandlePlayStatusUpdate();

  // NOW PLAYING LIST CHANGED
  virtual void HandleNowPlayingUpdate();
  virtual void HandleNowPlayingNotificationResponse(
      uint8_t label, bool interim, std::string curr_song_id,
      std::vector<SongInfo> song_list);

  // PLAY POSITION CHANGED
  virtual void HandlePlayPosUpdate();
  virtual void PlaybackPosNotificationResponse(uint8_t label, bool interim,
                                               PlayStatus status);

  // GET PLAY STATUS
  virtual void GetPlayStatusResponse(uint8_t label, PlayStatus status);
  virtual void PlaybackStatusNotificationResponse(uint8_t label, bool interim,
                                                  PlayStatus status);

  // PLAYER APPLICATION SETTINGS CHANGED
  virtual void HandlePlayerSettingChanged(
      std::vector<PlayerAttribute> attributes, std::vector<uint8_t> values);
  virtual void PlayerSettingChangedNotificationResponse(
      uint8_t label, bool interim, std::vector<PlayerAttribute> attributes,
      std::vector<uint8_t> values);

  // GET ELEMENT ATTRIBUTE
  // TODO (apanicke): Add a Handler function for this so if a specific device
  // needs to implement an interop fix, you only need to overload the one
  // function.
  virtual void GetElementAttributesResponse(
      uint8_t label, std::shared_ptr<GetElementAttributesRequest> pkt,
      SongInfo info);

  // AVAILABLE PLAYER CHANGED
  virtual void HandleAvailablePlayerUpdate();

  // ADDRESSED PLAYER CHANGED
  virtual void HandleAddressedPlayerUpdate();
  virtual void RejectNotification();
  virtual void AddressedPlayerNotificationResponse(
      uint8_t label, bool interim, uint16_t curr_player,
      std::vector<MediaPlayerInfo> /* unused */);

  // GET FOLDER ITEMS
  virtual void HandleGetFolderItems(
      uint8_t label, std::shared_ptr<GetFolderItemsRequest> request);
  virtual void GetMediaPlayerListResponse(
      uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt,
      uint16_t curr_player, std::vector<MediaPlayerInfo> players);
  virtual void GetVFSListResponse(uint8_t label,
                                  std::shared_ptr<GetFolderItemsRequest> pkt,
                                  std::vector<ListItem> items);
  virtual void GetNowPlayingListResponse(
      uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt,
      std::string curr_song_id, std::vector<SongInfo> song_list);

  // GET TOTAL NUMBER OF ITEMS
  virtual void HandleGetTotalNumberOfItems(
      uint8_t label, std::shared_ptr<GetTotalNumberOfItemsRequest> pkt);
  virtual void GetTotalNumberOfItemsMediaPlayersResponse(
      uint8_t label, uint16_t curr_player, std::vector<MediaPlayerInfo> list);
  virtual void GetTotalNumberOfItemsVFSResponse(uint8_t label,
                                                std::vector<ListItem> items);
  virtual void GetTotalNumberOfItemsNowPlayingResponse(
      uint8_t label, std::string curr_song_id, std::vector<SongInfo> song_list);

  // GET ITEM ATTRIBUTES
  virtual void HandleGetItemAttributes(
      uint8_t label, std::shared_ptr<GetItemAttributesRequest> request);
  virtual void GetItemAttributesNowPlayingResponse(
      uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt,
      std::string curr_media_id, std::vector<SongInfo> song_list);
  virtual void GetItemAttributesVFSResponse(
      uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt,
      std::vector<ListItem> item_list);

  // SET BROWSED PLAYER
  virtual void HandleSetBrowsedPlayer(
      uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> request);
  virtual void SetBrowsedPlayerResponse(
      uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> pkt, bool success,
      std::string root_id, uint32_t num_items);

  // CHANGE PATH
  virtual void HandleChangePath(uint8_t label,
                                std::shared_ptr<ChangePathRequest> request);
  virtual void ChangePathResponse(uint8_t label,
                                  std::shared_ptr<ChangePathRequest> request,
                                  std::vector<ListItem> list);

  // PLAY ITEM
  virtual void HandlePlayItem(uint8_t label,
                              std::shared_ptr<PlayItemRequest> request);

  // SET ADDRESSED PLAYER
  virtual void HandleSetAddressedPlayer(
      uint8_t label, std::shared_ptr<SetAddressedPlayerRequest> request,
      uint16_t curr_player, std::vector<MediaPlayerInfo> players);

  // LIST PLAYER APPLICATION SETTING ATTRIBUTES
  virtual void ListPlayerApplicationSettingAttributesResponse(
      uint8_t label, std::vector<PlayerAttribute> attributes);

  // LIST PLAYER APPLICATION SETTING VALUES
  virtual void ListPlayerApplicationSettingValuesResponse(
      uint8_t label, PlayerAttribute setting, std::vector<uint8_t> values);

  // GET CURRENT PLAYER APPLICATION SETTING VALUE
  virtual void GetPlayerApplicationSettingValueResponse(
      uint8_t label, std::vector<PlayerAttribute> attributes,
      std::vector<uint8_t> values);

  // SET PLAYER APPLICATION SETTING VALUE
  virtual void SetPlayerApplicationSettingValueResponse(uint8_t label,
                                                        CommandPdu pdu,
                                                        bool success);

  /********************
   * MESSAGE REQUESTS
   ********************/
  // VOLUME CHANGED NOTIFICATION
  virtual void RegisterVolumeChanged();
  virtual void HandleVolumeChanged(
      uint8_t label, const std::shared_ptr<RegisterNotificationResponse>& pkt);

  // SET VOLUME
  virtual void SetVolume(int8_t volume);

  /**
   * This function is called by Avrcp::ConnectionHandler to signify that
   * the remote device was disconnected.
   *
   * TODO (apanicke): Prevent allowing responses to messages while the device is
   * disconnected by using a weak pointer handle to the device when we separate
   * out the message handling. Also separate the logic in the future when
   * disconnecting only browsing (Though this shouldn't matter as if we are
   * disconnecting browsing then we should be fully disconnecting the device).
   */
  void DeviceDisconnected();

  friend std::ostream& operator<<(std::ostream& out, const Device& c);

 private:
  // This should always contain one item which represents the root id on the
  // current player.
  std::string CurrentFolder() const {
    if (current_path_.empty()) return "";
    return current_path_.top();
  }

  void send_message(uint8_t label, bool browse,
                    std::unique_ptr<::bluetooth::PacketBuilder> message) {
    active_labels_.erase(label);
    send_message_cb_.Run(label, browse, std::move(message));
  }
  base::WeakPtrFactory<Device> weak_ptr_factory_;

  // TODO (apanicke): Initialize all the variables in the constructor.
  RawAddress address_;

  // Enables AVRCP 1.3 Compatibility mode. This disables any AVRCP 1.4+ features
  // such as browsing and playlists but has the highest chance of working.
  bool avrcp13_compatibility_ = false;
  base::RepeatingCallback<void(
      uint8_t label, bool browse,
      std::unique_ptr<::bluetooth::PacketBuilder> message)>
      send_message_cb_;
  uint16_t ctrl_mtu_;
  uint16_t browse_mtu_;
  bool has_bip_client_;

  int curr_browsed_player_id_ = -1;

  std::stack<std::string> current_path_;

  // Notification Trackers
  using Notification = std::pair<bool, uint8_t>;
  Notification track_changed_ = Notification(false, 0);
  Notification play_status_changed_ = Notification(false, 0);
  Notification play_pos_changed_ = Notification(false, 0);
  Notification player_setting_changed_ = Notification(false, 0);
  Notification now_playing_changed_ = Notification(false, 0);
  Notification addr_player_changed_ = Notification(false, 0);
  Notification avail_players_changed_ = Notification(false, 0);
  Notification uids_changed_ = Notification(false, 0);

  MediaIdMap vfs_ids_;
  MediaIdMap now_playing_ids_;

  uint32_t play_pos_interval_ = 0;

  SongInfo last_song_info_;
  PlayStatus last_play_status_;

  base::CancelableClosure play_pos_update_cb_;

  MediaInterface* media_interface_ = nullptr;
  A2dpInterface* a2dp_interface_ = nullptr;
  VolumeInterface* volume_interface_ = nullptr;
  PlayerSettingsInterface* player_settings_interface_ = nullptr;

  // Labels used for messages currently in flight.
  std::set<uint8_t> active_labels_;

  int8_t volume_ = -1;
};

}  // namespace avrcp
}  // namespace bluetooth
