// 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.

// Handles NACK list and manages ACK.

#ifndef MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_
#define MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_

#include <stdint.h>

#include <deque>
#include <map>

#include "base/time/tick_clock.h"
#include "media/cast/net/rtp/rtp_defines.h"

namespace media {
namespace cast {

class Framer;
class RtpPayloadFeedback;

class CastMessageBuilder {
 public:
  CastMessageBuilder(base::TickClock* clock,
                     RtpPayloadFeedback* incoming_payload_feedback,
                     const Framer* framer,
                     uint32_t media_ssrc,
                     bool decoder_faster_than_max_frame_rate,
                     int max_unacked_frames);
  ~CastMessageBuilder();

  void CompleteFrameReceived(FrameId frame_id);
  bool TimeToSendNextCastMessage(base::TimeTicks* time_to_send);
  void UpdateCastMessage();

 private:
  bool UpdateAckMessage(FrameId frame_id);
  void BuildPacketList();
  bool UpdateCastMessageInternal(RtcpCastMessage* message);

  FrameId last_acked_frame_id() const { return cast_msg_.ack_frame_id; }

  base::TickClock* const clock_;  // Not owned by this class.
  RtpPayloadFeedback* const cast_feedback_;

  // CastMessageBuilder has only const access to the framer.
  const Framer* const framer_;
  const uint32_t media_ssrc_;
  const bool decoder_faster_than_max_frame_rate_;
  const int max_unacked_frames_;

  RtcpCastMessage cast_msg_;
  base::TimeTicks last_update_time_;

  std::map<FrameId, base::TimeTicks> time_last_nacked_map_;

  bool slowing_down_ack_;
  bool acked_last_frame_;
  std::deque<FrameId> ack_queue_;

  DISALLOW_COPY_AND_ASSIGN(CastMessageBuilder);
};

}  // namespace cast
}  // namespace media

#endif  //  MEDIA_CAST_NET_RTP_CAST_MESSAGE_BUILDER_H_
