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

#include "chrome/browser/media/cast_transport_host_filter.h"

#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/cast_messages.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/browser/browser_thread.h"
#include "device/power_save_blocker/power_save_blocker.h"
#include "media/cast/net/cast_transport.h"

namespace {

// How often to send raw events.
const int kSendRawEventsIntervalSecs = 1;

class TransportClient : public media::cast::CastTransport::Client {
 public:
  TransportClient(int32_t channel_id,
                  cast::CastTransportHostFilter* cast_transport_host_filter)
      : channel_id_(channel_id),
        cast_transport_host_filter_(cast_transport_host_filter) {}

  void OnStatusChanged(media::cast::CastTransportStatus status) final;
  void OnLoggingEventsReceived(
      std::unique_ptr<std::vector<media::cast::FrameEvent>> frame_events,
      std::unique_ptr<std::vector<media::cast::PacketEvent>> packet_events)
      final;
  void ProcessRtpPacket(std::unique_ptr<media::cast::Packet> packet) final;

 private:
  const int32_t channel_id_;
  cast::CastTransportHostFilter* const cast_transport_host_filter_;

  DISALLOW_COPY_AND_ASSIGN(TransportClient);
};

void TransportClient::OnStatusChanged(media::cast::CastTransportStatus status) {
  cast_transport_host_filter_->Send(
      new CastMsg_NotifyStatusChange(channel_id_, status));
}

void TransportClient::OnLoggingEventsReceived(
    std::unique_ptr<std::vector<media::cast::FrameEvent>> frame_events,
    std::unique_ptr<std::vector<media::cast::PacketEvent>> packet_events) {
  if (frame_events->empty() && packet_events->empty())
    return;
  cast_transport_host_filter_->Send(
      new CastMsg_RawEvents(channel_id_, *packet_events, *frame_events));
}

void TransportClient::ProcessRtpPacket(
    std::unique_ptr<media::cast::Packet> packet) {
  cast_transport_host_filter_->Send(
      new CastMsg_ReceivedPacket(channel_id_, *packet));
}

class RtcpClient : public media::cast::RtcpObserver {
 public:
  RtcpClient(
      int32_t channel_id,
      uint32_t rtp_sender_ssrc,
      base::WeakPtr<cast::CastTransportHostFilter> cast_transport_host_filter)
      : channel_id_(channel_id),
        rtp_sender_ssrc_(rtp_sender_ssrc),
        cast_transport_host_filter_(cast_transport_host_filter) {}

  void OnReceivedCastMessage(
      const media::cast::RtcpCastMessage& cast_message) override {
    if (cast_transport_host_filter_)
      cast_transport_host_filter_->Send(new CastMsg_RtcpCastMessage(
          channel_id_, rtp_sender_ssrc_, cast_message));
  }

  void OnReceivedRtt(base::TimeDelta round_trip_time) override {
    if (cast_transport_host_filter_)
      cast_transport_host_filter_->Send(
          new CastMsg_Rtt(channel_id_, rtp_sender_ssrc_, round_trip_time));
  }

  void OnReceivedPli() override {
    if (cast_transport_host_filter_)
      cast_transport_host_filter_->Send(
          new CastMsg_Pli(channel_id_, rtp_sender_ssrc_));
  }

 private:
  const int32_t channel_id_;
  const uint32_t rtp_sender_ssrc_;
  const base::WeakPtr<cast::CastTransportHostFilter>
      cast_transport_host_filter_;

  DISALLOW_COPY_AND_ASSIGN(RtcpClient);
};

}  // namespace

namespace cast {

CastTransportHostFilter::CastTransportHostFilter()
    : BrowserMessageFilter(CastMsgStart),
      weak_factory_(this) {}

CastTransportHostFilter::~CastTransportHostFilter() {}

void CastTransportHostFilter::OnStatusChanged(
    int32_t channel_id,
    media::cast::CastTransportStatus status) {
  Send(new CastMsg_NotifyStatusChange(channel_id, status));
}

bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message)
    IPC_MESSAGE_HANDLER(CastHostMsg_New, OnNew)
    IPC_MESSAGE_HANDLER(CastHostMsg_Delete, OnDelete)
    IPC_MESSAGE_HANDLER(CastHostMsg_InitializeAudio, OnInitializeAudio)
    IPC_MESSAGE_HANDLER(CastHostMsg_InitializeVideo, OnInitializeVideo)
    IPC_MESSAGE_HANDLER(CastHostMsg_InsertFrame, OnInsertFrame)
    IPC_MESSAGE_HANDLER(CastHostMsg_SendSenderReport,
                        OnSendSenderReport)
    IPC_MESSAGE_HANDLER(CastHostMsg_ResendFrameForKickstart,
                        OnResendFrameForKickstart)
    IPC_MESSAGE_HANDLER(CastHostMsg_CancelSendingFrames,
                        OnCancelSendingFrames)
    IPC_MESSAGE_HANDLER(CastHostMsg_AddValidRtpReceiver, OnAddValidRtpReceiver)
    IPC_MESSAGE_HANDLER(CastHostMsg_InitializeRtpReceiverRtcpBuilder,
                        OnInitializeRtpReceiverRtcpBuilder)
    IPC_MESSAGE_HANDLER(CastHostMsg_AddCastFeedback, OnAddCastFeedback)
    IPC_MESSAGE_HANDLER(CastHostMsg_AddPli, OnAddPli)
    IPC_MESSAGE_HANDLER(CastHostMsg_AddRtcpEvents, OnAddRtcpEvents)
    IPC_MESSAGE_HANDLER(CastHostMsg_AddRtpReceiverReport,
                        OnAddRtpReceiverReport)
    IPC_MESSAGE_HANDLER(CastHostMsg_SendRtcpFromRtpReceiver,
                        OnSendRtcpFromRtpReceiver)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void CastTransportHostFilter::OnNew(int32_t channel_id,
                                    const net::IPEndPoint& local_end_point,
                                    const net::IPEndPoint& remote_end_point,
                                    const base::DictionaryValue& options) {
  if (!power_save_blocker_) {
    DVLOG(1) << ("Preventing the application from being suspended while one or "
                 "more transports are active for Cast Streaming.");
    power_save_blocker_.reset(new device::PowerSaveBlocker(
        device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
        device::PowerSaveBlocker::kReasonOther,
        "Cast is streaming content to a remote receiver",
        content::BrowserThread::GetMessageLoopProxyForThread(
            content::BrowserThread::UI),
        content::BrowserThread::GetMessageLoopProxyForThread(
            content::BrowserThread::FILE)));
  }

  if (id_map_.Lookup(channel_id)) {
    id_map_.Remove(channel_id);
  }

  std::unique_ptr<media::cast::UdpTransport> udp_transport(
      new media::cast::UdpTransport(
          g_browser_process->net_log(), base::ThreadTaskRunnerHandle::Get(),
          local_end_point, remote_end_point,
          base::Bind(&CastTransportHostFilter::OnStatusChanged,
                     weak_factory_.GetWeakPtr(), channel_id)));
  udp_transport->SetUdpOptions(options);
  std::unique_ptr<media::cast::CastTransport> sender =
      media::cast::CastTransport::Create(
          &clock_, base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
          base::WrapUnique(new TransportClient(channel_id, this)),
          std::move(udp_transport), base::ThreadTaskRunnerHandle::Get());
  sender->SetOptions(options);
  id_map_.AddWithID(sender.release(), channel_id);
}

void CastTransportHostFilter::OnDelete(int32_t channel_id) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    id_map_.Remove(channel_id);
  } else {
    DVLOG(1) << "CastTransportHostFilter::Delete called "
             << "on non-existing channel";
  }

  if (id_map_.IsEmpty()) {
    DVLOG_IF(1, power_save_blocker_) <<
        ("Releasing the block on application suspension since no transports "
         "are active anymore for Cast Streaming.");
    power_save_blocker_.reset();
  }
}

// TODO(xjz): Replace all the separate "init/start audio" and "init/start video"
// methods with a single "init/start rtp stream" that handles either media type.
void CastTransportHostFilter::OnInitializeAudio(
    int32_t channel_id,
    const media::cast::CastTransportRtpConfig& config) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->InitializeAudio(
        config, base::WrapUnique(new RtcpClient(channel_id, config.ssrc,
                                                weak_factory_.GetWeakPtr())));
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
  }
}

void CastTransportHostFilter::OnInitializeVideo(
    int32_t channel_id,
    const media::cast::CastTransportRtpConfig& config) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->InitializeVideo(
        config, base::WrapUnique(new RtcpClient(channel_id, config.ssrc,
                                                weak_factory_.GetWeakPtr())));
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
  }
}

void CastTransportHostFilter::OnInsertFrame(
    int32_t channel_id,
    uint32_t ssrc,
    const media::cast::EncodedFrame& frame) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->InsertFrame(ssrc, frame);
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnInsertFrame on non-existing channel";
  }
}

void CastTransportHostFilter::OnCancelSendingFrames(
    int32_t channel_id,
    uint32_t ssrc,
    const std::vector<media::cast::FrameId>& frame_ids) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->CancelSendingFrames(ssrc, frame_ids);
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnCancelSendingFrames "
        << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnResendFrameForKickstart(
    int32_t channel_id,
    uint32_t ssrc,
    media::cast::FrameId frame_id) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->ResendFrameForKickstart(ssrc, frame_id);
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnResendFrameForKickstart "
        << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnSendSenderReport(
    int32_t channel_id,
    uint32_t ssrc,
    base::TimeTicks current_time,
    media::cast::RtpTimeTicks current_time_as_rtp_timestamp) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->SendSenderReport(ssrc,
                             current_time,
                             current_time_as_rtp_timestamp);
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnSendSenderReport "
        << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnAddValidRtpReceiver(
    int32_t channel_id,
    uint32_t rtp_sender_ssrc,
    uint32_t rtp_receiver_ssrc) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->AddValidRtpReceiver(rtp_sender_ssrc, rtp_receiver_ssrc);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnAddValidRtpReceiver "
             << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnInitializeRtpReceiverRtcpBuilder(
    int32_t channel_id,
    uint32_t rtp_receiver_ssrc,
    const media::cast::RtcpTimeData& time_data) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->InitializeRtpReceiverRtcpBuilder(rtp_receiver_ssrc, time_data);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnInitializeRtpReceiverRtcpBuilder "
             << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnAddCastFeedback(
    int32_t channel_id,
    const media::cast::RtcpCastMessage& cast_message,
    base::TimeDelta target_delay) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->AddCastFeedback(cast_message, target_delay);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnAddCastFeedback "
             << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnAddPli(
    int32_t channel_id,
    const media::cast::RtcpPliMessage& pli_message) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->AddPli(pli_message);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnAddPli on non-existing channel";
  }
}

void CastTransportHostFilter::OnAddRtcpEvents(
    int32_t channel_id,
    const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents& rtcp_events) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->AddRtcpEvents(rtcp_events);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnAddRtcpEvents "
             << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnAddRtpReceiverReport(
    int32_t channel_id,
    const media::cast::RtcpReportBlock& rtp_receiver_report_block) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->AddRtpReceiverReport(rtp_receiver_report_block);
  } else {
    DVLOG(1) << "CastTransportHostFilter::OnAddRtpReceiverReport "
             << "on non-existing channel";
  }
}

void CastTransportHostFilter::OnSendRtcpFromRtpReceiver(int32_t channel_id) {
  media::cast::CastTransport* sender = id_map_.Lookup(channel_id);
  if (sender) {
    sender->SendRtcpFromRtpReceiver();
  } else {
    DVLOG(1)
        << "CastTransportHostFilter::OnSendRtcpFromRtpReceiver "
        << "on non-existing channel";
  }
}

}  // namespace cast
