/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_CALL_RTC_EVENT_LOG_H_
#define WEBRTC_CALL_RTC_EVENT_LOG_H_

#include <memory>
#include <string>

#include "webrtc/base/platform_file.h"
#include "webrtc/video_receive_stream.h"
#include "webrtc/video_send_stream.h"

namespace webrtc {

// Forward declaration of storage class that is automatically generated from
// the protobuf file.
namespace rtclog {
class EventStream;
}  // namespace rtclog

class Clock;
class RtcEventLogImpl;

enum class MediaType;

enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket };

class RtcEventLog {
 public:
  virtual ~RtcEventLog() {}

  // Factory method to create an RtcEventLog object.
  static std::unique_ptr<RtcEventLog> Create(const Clock* clock);

  // Create an RtcEventLog object that does nothing.
  static std::unique_ptr<RtcEventLog> CreateNull();

  // Starts logging a maximum of max_size_bytes bytes to the specified file.
  // If the file already exists it will be overwritten.
  // If max_size_bytes <= 0, logging will be active until StopLogging is called.
  // The function has no effect and returns false if we can't start a new log
  // e.g. because we are already logging or the file cannot be opened.
  virtual bool StartLogging(const std::string& file_name,
                            int64_t max_size_bytes) = 0;

  // Same as above. The RtcEventLog takes ownership of the file if the call
  // is successful, i.e. if it returns true.
  virtual bool StartLogging(rtc::PlatformFile platform_file,
                            int64_t max_size_bytes) = 0;

  // Deprecated. Pass an explicit file size limit.
  bool StartLogging(const std::string& file_name) {
    return StartLogging(file_name, 10000000);
  }

  // Deprecated. Pass an explicit file size limit.
  bool StartLogging(rtc::PlatformFile platform_file) {
    return StartLogging(platform_file, 10000000);
  }

  // Stops logging to file and waits until the thread has finished.
  virtual void StopLogging() = 0;

  // Logs configuration information for webrtc::VideoReceiveStream.
  virtual void LogVideoReceiveStreamConfig(
      const webrtc::VideoReceiveStream::Config& config) = 0;

  // Logs configuration information for webrtc::VideoSendStream.
  virtual void LogVideoSendStreamConfig(
      const webrtc::VideoSendStream::Config& config) = 0;

  // Logs the header of an incoming or outgoing RTP packet. packet_length
  // is the total length of the packet, including both header and payload.
  virtual void LogRtpHeader(PacketDirection direction,
                            MediaType media_type,
                            const uint8_t* header,
                            size_t packet_length) = 0;

  // Logs an incoming or outgoing RTCP packet.
  virtual void LogRtcpPacket(PacketDirection direction,
                             MediaType media_type,
                             const uint8_t* packet,
                             size_t length) = 0;

  // Logs an audio playout event.
  virtual void LogAudioPlayout(uint32_t ssrc) = 0;

  // Logs a bitrate update from the bandwidth estimator based on packet loss.
  virtual void LogBwePacketLossEvent(int32_t bitrate,
                                     uint8_t fraction_loss,
                                     int32_t total_packets) = 0;

  // Reads an RtcEventLog file and returns true when reading was successful.
  // The result is stored in the given EventStream object.
  // The order of the events in the EventStream is implementation defined.
  // The current implementation writes a LOG_START event, then the old
  // configurations, then the remaining events in timestamp order and finally
  // a LOG_END event. However, this might change without further notice.
  // TODO(terelius): Change result type to a vector?
  static bool ParseRtcEventLog(const std::string& file_name,
                               rtclog::EventStream* result);
};

// No-op implementation is used if flag is not set, or in tests.
class RtcEventLogNullImpl final : public RtcEventLog {
 public:
  bool StartLogging(const std::string& file_name,
                    int64_t max_size_bytes) override {
    return false;
  }
  bool StartLogging(rtc::PlatformFile platform_file,
                    int64_t max_size_bytes) override;
  void StopLogging() override {}
  void LogVideoReceiveStreamConfig(
      const VideoReceiveStream::Config& config) override {}
  void LogVideoSendStreamConfig(
      const VideoSendStream::Config& config) override {}
  void LogRtpHeader(PacketDirection direction,
                    MediaType media_type,
                    const uint8_t* header,
                    size_t packet_length) override {}
  void LogRtcpPacket(PacketDirection direction,
                     MediaType media_type,
                     const uint8_t* packet,
                     size_t length) override {}
  void LogAudioPlayout(uint32_t ssrc) override {}
  void LogBwePacketLossEvent(int32_t bitrate,
                             uint8_t fraction_loss,
                             int32_t total_packets) override {}
};

}  // namespace webrtc

#endif  // WEBRTC_CALL_RTC_EVENT_LOG_H_
