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

// Test application that simulates a cast sender - Data can be either generated
// or read from a file.

#include <stdint.h>

#include <memory>
#include <queue>
#include <utility>

#include "base/at_exit.h"
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/time/default_tick_clock.h"
#include "base/values.h"
#include "media/base/media.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/cast_sender.h"
#include "media/cast/logging/encoding_event_subscriber.h"
#include "media/cast/logging/log_serializer.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/logging/proto/raw_events.pb.h"
#include "media/cast/logging/receiver_time_offset_estimator_impl.h"
#include "media/cast/logging/stats_event_subscriber.h"
#include "media/cast/net/cast_transport.h"
#include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/udp_transport.h"
#include "media/cast/test/fake_media_source.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/input_builder.h"

namespace {

// The max allowed size of serialized log.
const int kMaxSerializedLogBytes = 10 * 1000 * 1000;

// Flags for this program:
//
// --address=xx.xx.xx.xx
//   IP address of receiver.
//
// --port=xxxx
//   Port number of receiver.
//
// --source-file=xxx.webm
//   WebM file as source of video frames.
//
// --fps=xx
//   Override framerate of the video stream.
//
// --vary-frame-sizes
//   Randomly vary the video frame sizes at random points in time.  Has no
//   effect if --source-file is being used.
const char kSwitchAddress[] = "address";
const char kSwitchPort[] = "port";
const char kSwitchSourceFile[] = "source-file";
const char kSwitchFps[] = "fps";
const char kSwitchVaryFrameSizes[] = "vary-frame-sizes";

void UpdateCastTransportStatus(media::cast::CastTransportStatus status) {
  VLOG(1) << "Transport status: " << status;
}

void QuitLoopOnInitializationResult(media::cast::OperationalStatus result) {
  CHECK(result == media::cast::STATUS_INITIALIZED)
      << "Cast sender uninitialized";
  base::MessageLoop::current()->QuitWhenIdle();
}

net::IPEndPoint CreateUDPAddress(const std::string& ip_str, uint16_t port) {
  net::IPAddress ip_address;
  CHECK(ip_address.AssignFromIPLiteral(ip_str));
  return net::IPEndPoint(ip_address, port);
}

void DumpLoggingData(const media::cast::proto::LogMetadata& log_metadata,
                     const media::cast::FrameEventList& frame_events,
                     const media::cast::PacketEventList& packet_events,
                     base::ScopedFILE log_file) {
  VLOG(0) << "Frame map size: " << frame_events.size();
  VLOG(0) << "Packet map size: " << packet_events.size();

  std::unique_ptr<char[]> event_log(new char[kMaxSerializedLogBytes]);
  int event_log_bytes;
  if (!media::cast::SerializeEvents(log_metadata, frame_events, packet_events,
                                    true, kMaxSerializedLogBytes,
                                    event_log.get(), &event_log_bytes)) {
    VLOG(0) << "Failed to serialize events.";
    return;
  }

  VLOG(0) << "Events serialized length: " << event_log_bytes;

  int ret = fwrite(event_log.get(), 1, event_log_bytes, log_file.get());
  if (ret != event_log_bytes) VLOG(0) << "Failed to write logs to file.";
}

void WriteLogsToFileAndDestroySubscribers(
    const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
    std::unique_ptr<media::cast::EncodingEventSubscriber>
        video_event_subscriber,
    std::unique_ptr<media::cast::EncodingEventSubscriber>
        audio_event_subscriber,
    base::ScopedFILE video_log_file, base::ScopedFILE audio_log_file) {
  cast_environment->logger()->Unsubscribe(video_event_subscriber.get());
  cast_environment->logger()->Unsubscribe(audio_event_subscriber.get());

  VLOG(0) << "Dumping logging data for video stream.";
  media::cast::proto::LogMetadata log_metadata;
  media::cast::FrameEventList frame_events;
  media::cast::PacketEventList packet_events;
  video_event_subscriber->GetEventsAndReset(&log_metadata, &frame_events,
                                            &packet_events);

  DumpLoggingData(log_metadata, frame_events, packet_events,
                  std::move(video_log_file));

  VLOG(0) << "Dumping logging data for audio stream.";
  audio_event_subscriber->GetEventsAndReset(&log_metadata, &frame_events,
                                            &packet_events);

  DumpLoggingData(log_metadata, frame_events, packet_events,
                  std::move(audio_log_file));
}

void WriteStatsAndDestroySubscribers(
    const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
    std::unique_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber,
    std::unique_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber,
    std::unique_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> estimator) {
  cast_environment->logger()->Unsubscribe(video_stats_subscriber.get());
  cast_environment->logger()->Unsubscribe(audio_stats_subscriber.get());
  cast_environment->logger()->Unsubscribe(estimator.get());

  std::unique_ptr<base::DictionaryValue> stats =
      video_stats_subscriber->GetStats();
  std::string json;
  base::JSONWriter::WriteWithOptions(
      *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
  VLOG(0) << "Video stats: " << json;

  stats = audio_stats_subscriber->GetStats();
  json.clear();
  base::JSONWriter::WriteWithOptions(
      *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
  VLOG(0) << "Audio stats: " << json;
}

class TransportClient : public media::cast::CastTransport::Client {
 public:
  explicit TransportClient(
      media::cast::LogEventDispatcher* log_event_dispatcher)
      : log_event_dispatcher_(log_event_dispatcher) {}

  void OnStatusChanged(media::cast::CastTransportStatus status) final {
    VLOG(1) << "Transport status: " << status;
  };
  void OnLoggingEventsReceived(
      std::unique_ptr<std::vector<media::cast::FrameEvent>> frame_events,
      std::unique_ptr<std::vector<media::cast::PacketEvent>> packet_events)
      final {
    DCHECK(log_event_dispatcher_);
    log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events),
                                                 std::move(packet_events));
  };
  void ProcessRtpPacket(std::unique_ptr<media::cast::Packet> packet) final {}

 private:
  media::cast::LogEventDispatcher* const
      log_event_dispatcher_;  // Not owned by this class.

  DISALLOW_COPY_AND_ASSIGN(TransportClient);
};

}  // namespace

int main(int argc, char** argv) {
  base::AtExitManager at_exit;
  base::CommandLine::Init(argc, argv);
  InitLogging(logging::LoggingSettings());

  // Prepare media module for FFmpeg decoding.
  media::InitializeMediaLibrary();

  base::Thread test_thread("Cast sender test app thread");
  base::Thread audio_thread("Cast audio encoder thread");
  base::Thread video_thread("Cast video encoder thread");
  test_thread.Start();
  audio_thread.Start();
  video_thread.Start();

  base::MessageLoopForIO io_message_loop;

  // Default parameters.
  base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
  std::string remote_ip_address = cmd->GetSwitchValueASCII(kSwitchAddress);
  if (remote_ip_address.empty()) remote_ip_address = "127.0.0.1";
  int remote_port = 0;
  if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchPort), &remote_port) ||
      remote_port < 0 || remote_port > 65535) {
    remote_port = 2344;
  }
  LOG(INFO) << "Sending to " << remote_ip_address << ":" << remote_port << ".";

  media::cast::FrameSenderConfig audio_config =
      media::cast::GetDefaultAudioSenderConfig();
  media::cast::FrameSenderConfig video_config =
      media::cast::GetDefaultVideoSenderConfig();

  // Running transport on the main thread.
  // Setting up transport config.
  net::IPEndPoint remote_endpoint =
      CreateUDPAddress(remote_ip_address, static_cast<uint16_t>(remote_port));

  // Enable raw event and stats logging.
  // Running transport on the main thread.
  scoped_refptr<media::cast::CastEnvironment> cast_environment(
      new media::cast::CastEnvironment(
          base::WrapUnique<base::TickClock>(new base::DefaultTickClock()),
          io_message_loop.task_runner(), audio_thread.task_runner(),
          video_thread.task_runner()));

  // SendProcess initialization.
  std::unique_ptr<media::cast::FakeMediaSource> fake_media_source(
      new media::cast::FakeMediaSource(test_thread.task_runner(),
                                       cast_environment->Clock(), audio_config,
                                       video_config, false));

  int final_fps = 0;
  if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps), &final_fps)) {
    final_fps = 0;
  }
  base::FilePath source_path = cmd->GetSwitchValuePath(kSwitchSourceFile);
  if (!source_path.empty()) {
    LOG(INFO) << "Source: " << source_path.value();
    fake_media_source->SetSourceFile(source_path, final_fps);
  }
  if (cmd->HasSwitch(kSwitchVaryFrameSizes))
    fake_media_source->SetVariableFrameSizeMode(true);

  // CastTransport initialization.
  std::unique_ptr<media::cast::CastTransport> transport_sender =
      media::cast::CastTransport::Create(
          cast_environment->Clock(), base::TimeDelta::FromSeconds(1),
          base::MakeUnique<TransportClient>(cast_environment->logger()),
          base::MakeUnique<media::cast::UdpTransport>(
              nullptr, io_message_loop.task_runner(), net::IPEndPoint(),
              remote_endpoint, base::Bind(&UpdateCastTransportStatus)),
          io_message_loop.task_runner());

  // Set up event subscribers.
  std::unique_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber;
  std::unique_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber;
  std::string video_log_file_name("/tmp/video_events.log.gz");
  std::string audio_log_file_name("/tmp/audio_events.log.gz");
  LOG(INFO) << "Logging audio events to: " << audio_log_file_name;
  LOG(INFO) << "Logging video events to: " << video_log_file_name;
  video_event_subscriber.reset(new media::cast::EncodingEventSubscriber(
      media::cast::VIDEO_EVENT, 10000));
  audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber(
      media::cast::AUDIO_EVENT, 10000));
  cast_environment->logger()->Subscribe(video_event_subscriber.get());
  cast_environment->logger()->Subscribe(audio_event_subscriber.get());

  // Subscribers for stats.
  std::unique_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl>
      offset_estimator(new media::cast::ReceiverTimeOffsetEstimatorImpl());
  cast_environment->logger()->Subscribe(offset_estimator.get());
  std::unique_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber(
      new media::cast::StatsEventSubscriber(media::cast::VIDEO_EVENT,
                                            cast_environment->Clock(),
                                            offset_estimator.get()));
  std::unique_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber(
      new media::cast::StatsEventSubscriber(media::cast::AUDIO_EVENT,
                                            cast_environment->Clock(),
                                            offset_estimator.get()));
  cast_environment->logger()->Subscribe(video_stats_subscriber.get());
  cast_environment->logger()->Subscribe(audio_stats_subscriber.get());

  base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w"));
  if (!video_log_file) {
    VLOG(1) << "Failed to open video log file for writing.";
    exit(-1);
  }

  base::ScopedFILE audio_log_file(fopen(audio_log_file_name.c_str(), "w"));
  if (!audio_log_file) {
    VLOG(1) << "Failed to open audio log file for writing.";
    exit(-1);
  }

  const int logging_duration_seconds = 10;
  io_message_loop.task_runner()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&WriteLogsToFileAndDestroySubscribers, cast_environment,
                 base::Passed(&video_event_subscriber),
                 base::Passed(&audio_event_subscriber),
                 base::Passed(&video_log_file), base::Passed(&audio_log_file)),
      base::TimeDelta::FromSeconds(logging_duration_seconds));

  io_message_loop.task_runner()->PostDelayedTask(
      FROM_HERE, base::Bind(&WriteStatsAndDestroySubscribers, cast_environment,
                            base::Passed(&video_stats_subscriber),
                            base::Passed(&audio_stats_subscriber),
                            base::Passed(&offset_estimator)),
      base::TimeDelta::FromSeconds(logging_duration_seconds));

  // CastSender initialization.
  std::unique_ptr<media::cast::CastSender> cast_sender =
      media::cast::CastSender::Create(cast_environment, transport_sender.get());
  io_message_loop.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&media::cast::CastSender::InitializeVideo,
                 base::Unretained(cast_sender.get()),
                 fake_media_source->get_video_config(),
                 base::Bind(&QuitLoopOnInitializationResult),
                 media::cast::CreateDefaultVideoEncodeAcceleratorCallback(),
                 media::cast::CreateDefaultVideoEncodeMemoryCallback()));
  base::RunLoop().Run();  // Wait for video initialization.
  io_message_loop.task_runner()->PostTask(
      FROM_HERE, base::Bind(&media::cast::CastSender::InitializeAudio,
                            base::Unretained(cast_sender.get()), audio_config,
                            base::Bind(&QuitLoopOnInitializationResult)));
  base::RunLoop().Run();  // Wait for audio initialization.

  fake_media_source->Start(cast_sender->audio_frame_input(),
                           cast_sender->video_frame_input());
  base::RunLoop().Run();
  return 0;
}
