/*
 *  Copyright (c) 2016 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 RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_H_
#define RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "modules/audio_coding/neteq/tools/neteq_stats_getter.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_tools/rtc_event_log_visualizer/plot_base.h"
#include "rtc_tools/rtc_event_log_visualizer/triage_notifications.h"

namespace webrtc {

class AnalyzerConfig {
 public:
  float GetCallTimeSec(int64_t timestamp_us) const {
    int64_t offset = normalize_time_ ? begin_time_ : 0;
    return static_cast<float>(timestamp_us - offset) / 1000000;
  }

  float CallBeginTimeSec() const { return GetCallTimeSec(begin_time_); }

  float CallEndTimeSec() const { return GetCallTimeSec(end_time_); }

  // Window and step size used for calculating moving averages, e.g. bitrate.
  // The generated data points will be |step_| microseconds apart.
  // Only events occurring at most |window_duration_| microseconds before the
  // current data point will be part of the average.
  int64_t window_duration_;
  int64_t step_;

  // First and last events of the log.
  int64_t begin_time_;
  int64_t end_time_;
  bool normalize_time_;
};

class EventLogAnalyzer {
 public:
  // The EventLogAnalyzer keeps a reference to the ParsedRtcEventLogNew for the
  // duration of its lifetime. The ParsedRtcEventLogNew must not be destroyed or
  // modified while the EventLogAnalyzer is being used.
  EventLogAnalyzer(const ParsedRtcEventLog& log, bool normalize_time);

  void CreatePacketGraph(PacketDirection direction, Plot* plot);

  void CreateRtcpTypeGraph(PacketDirection direction, Plot* plot);

  void CreateAccumulatedPacketsGraph(PacketDirection direction, Plot* plot);

  void CreatePlayoutGraph(Plot* plot);

  void CreateAudioLevelGraph(PacketDirection direction, Plot* plot);

  void CreateSequenceNumberGraph(Plot* plot);

  void CreateIncomingPacketLossGraph(Plot* plot);

  void CreateIncomingDelayGraph(Plot* plot);

  void CreateFractionLossGraph(Plot* plot);

  void CreateTotalIncomingBitrateGraph(Plot* plot);
  void CreateTotalOutgoingBitrateGraph(Plot* plot,
                                       bool show_detector_state = false,
                                       bool show_alr_state = false);

  void CreateStreamBitrateGraph(PacketDirection direction, Plot* plot);
  void CreateBitrateAllocationGraph(PacketDirection direction, Plot* plot);

  void CreateGoogCcSimulationGraph(Plot* plot);
  void CreateSendSideBweSimulationGraph(Plot* plot);
  void CreateReceiveSideBweSimulationGraph(Plot* plot);

  void CreateNetworkDelayFeedbackGraph(Plot* plot);
  void CreatePacerDelayGraph(Plot* plot);

  void CreateTimestampGraph(PacketDirection direction, Plot* plot);
  void CreateSenderAndReceiverReportPlot(
      PacketDirection direction,
      rtc::FunctionView<float(const rtcp::ReportBlock&)> fy,
      std::string title,
      std::string yaxis_label,
      Plot* plot);

  void CreateAudioEncoderTargetBitrateGraph(Plot* plot);
  void CreateAudioEncoderFrameLengthGraph(Plot* plot);
  void CreateAudioEncoderPacketLossGraph(Plot* plot);
  void CreateAudioEncoderEnableFecGraph(Plot* plot);
  void CreateAudioEncoderEnableDtxGraph(Plot* plot);
  void CreateAudioEncoderNumChannelsGraph(Plot* plot);

  using NetEqStatsGetterMap =
      std::map<uint32_t, std::unique_ptr<test::NetEqStatsGetter>>;
  NetEqStatsGetterMap SimulateNetEq(const std::string& replacement_file_name,
                                    int file_sample_rate_hz) const;

  void CreateAudioJitterBufferGraph(uint32_t ssrc,
                                    const test::NetEqStatsGetter* stats_getter,
                                    Plot* plot) const;
  void CreateNetEqNetworkStatsGraph(
      const NetEqStatsGetterMap& neteq_stats_getters,
      rtc::FunctionView<float(const NetEqNetworkStatistics&)> stats_extractor,
      const std::string& plot_name,
      Plot* plot) const;
  void CreateNetEqLifetimeStatsGraph(
      const NetEqStatsGetterMap& neteq_stats_getters,
      rtc::FunctionView<float(const NetEqLifetimeStatistics&)> stats_extractor,
      const std::string& plot_name,
      Plot* plot) const;

  void CreateIceCandidatePairConfigGraph(Plot* plot);
  void CreateIceConnectivityCheckGraph(Plot* plot);

  void CreateDtlsTransportStateGraph(Plot* plot);
  void CreateDtlsWritableStateGraph(Plot* plot);

  void CreateTriageNotifications();
  void PrintNotifications(FILE* file);

 private:
  struct LayerDescription {
    LayerDescription(uint32_t ssrc,
                     uint8_t spatial_layer,
                     uint8_t temporal_layer)
        : ssrc(ssrc),
          spatial_layer(spatial_layer),
          temporal_layer(temporal_layer) {}
    bool operator<(const LayerDescription& other) const {
      if (ssrc != other.ssrc)
        return ssrc < other.ssrc;
      if (spatial_layer != other.spatial_layer)
        return spatial_layer < other.spatial_layer;
      return temporal_layer < other.temporal_layer;
    }
    uint32_t ssrc;
    uint8_t spatial_layer;
    uint8_t temporal_layer;
  };

  bool IsRtxSsrc(PacketDirection direction, uint32_t ssrc) const {
    if (direction == kIncomingPacket) {
      return parsed_log_.incoming_rtx_ssrcs().find(ssrc) !=
             parsed_log_.incoming_rtx_ssrcs().end();
    } else {
      return parsed_log_.outgoing_rtx_ssrcs().find(ssrc) !=
             parsed_log_.outgoing_rtx_ssrcs().end();
    }
  }

  bool IsVideoSsrc(PacketDirection direction, uint32_t ssrc) const {
    if (direction == kIncomingPacket) {
      return parsed_log_.incoming_video_ssrcs().find(ssrc) !=
             parsed_log_.incoming_video_ssrcs().end();
    } else {
      return parsed_log_.outgoing_video_ssrcs().find(ssrc) !=
             parsed_log_.outgoing_video_ssrcs().end();
    }
  }

  bool IsAudioSsrc(PacketDirection direction, uint32_t ssrc) const {
    if (direction == kIncomingPacket) {
      return parsed_log_.incoming_audio_ssrcs().find(ssrc) !=
             parsed_log_.incoming_audio_ssrcs().end();
    } else {
      return parsed_log_.outgoing_audio_ssrcs().find(ssrc) !=
             parsed_log_.outgoing_audio_ssrcs().end();
    }
  }

  template <typename NetEqStatsType>
  void CreateNetEqStatsGraphInternal(
      const NetEqStatsGetterMap& neteq_stats,
      rtc::FunctionView<const std::vector<std::pair<int64_t, NetEqStatsType>>*(
          const test::NetEqStatsGetter*)> data_extractor,
      rtc::FunctionView<float(const NetEqStatsType&)> stats_extractor,
      const std::string& plot_name,
      Plot* plot) const;

  template <typename IterableType>
  void CreateAccumulatedPacketsTimeSeries(Plot* plot,
                                          const IterableType& packets,
                                          const std::string& label);

  void CreateStreamGapAlerts(PacketDirection direction);
  void CreateTransmissionGapAlerts(PacketDirection direction);

  std::string GetStreamName(PacketDirection direction, uint32_t ssrc) const {
    char buffer[200];
    rtc::SimpleStringBuilder name(buffer);
    if (IsAudioSsrc(direction, ssrc)) {
      name << "Audio ";
    } else if (IsVideoSsrc(direction, ssrc)) {
      name << "Video ";
    } else {
      name << "Unknown ";
    }
    if (IsRtxSsrc(direction, ssrc)) {
      name << "RTX ";
    }
    if (direction == kIncomingPacket)
      name << "(In) ";
    else
      name << "(Out) ";
    name << "SSRC " << ssrc;
    return name.str();
  }

  std::string GetLayerName(LayerDescription layer) const {
    char buffer[100];
    rtc::SimpleStringBuilder name(buffer);
    name << "SSRC " << layer.ssrc << " sl " << layer.spatial_layer << ", tl "
         << layer.temporal_layer;
    return name.str();
  }

  void Alert_RtpLogTimeGap(PacketDirection direction,
                           float time_seconds,
                           int64_t duration) {
    if (direction == kIncomingPacket) {
      incoming_rtp_recv_time_gaps_.emplace_back(time_seconds, duration);
    } else {
      outgoing_rtp_send_time_gaps_.emplace_back(time_seconds, duration);
    }
  }

  void Alert_RtcpLogTimeGap(PacketDirection direction,
                            float time_seconds,
                            int64_t duration) {
    if (direction == kIncomingPacket) {
      incoming_rtcp_recv_time_gaps_.emplace_back(time_seconds, duration);
    } else {
      outgoing_rtcp_send_time_gaps_.emplace_back(time_seconds, duration);
    }
  }

  void Alert_SeqNumJump(PacketDirection direction,
                        float time_seconds,
                        uint32_t ssrc) {
    if (direction == kIncomingPacket) {
      incoming_seq_num_jumps_.emplace_back(time_seconds, ssrc);
    } else {
      outgoing_seq_num_jumps_.emplace_back(time_seconds, ssrc);
    }
  }

  void Alert_CaptureTimeJump(PacketDirection direction,
                             float time_seconds,
                             uint32_t ssrc) {
    if (direction == kIncomingPacket) {
      incoming_capture_time_jumps_.emplace_back(time_seconds, ssrc);
    } else {
      outgoing_capture_time_jumps_.emplace_back(time_seconds, ssrc);
    }
  }

  void Alert_OutgoingHighLoss(double avg_loss_fraction) {
    outgoing_high_loss_alerts_.emplace_back(avg_loss_fraction);
  }

  std::string GetCandidatePairLogDescriptionFromId(uint32_t candidate_pair_id);

  const ParsedRtcEventLog& parsed_log_;

  // A list of SSRCs we are interested in analysing.
  // If left empty, all SSRCs will be considered relevant.
  std::vector<uint32_t> desired_ssrc_;

  // Stores the timestamps for all log segments, in the form of associated start
  // and end events.
  std::vector<std::pair<int64_t, int64_t>> log_segments_;

  std::vector<IncomingRtpReceiveTimeGap> incoming_rtp_recv_time_gaps_;
  std::vector<IncomingRtcpReceiveTimeGap> incoming_rtcp_recv_time_gaps_;
  std::vector<OutgoingRtpSendTimeGap> outgoing_rtp_send_time_gaps_;
  std::vector<OutgoingRtcpSendTimeGap> outgoing_rtcp_send_time_gaps_;
  std::vector<IncomingSeqNumJump> incoming_seq_num_jumps_;
  std::vector<IncomingCaptureTimeJump> incoming_capture_time_jumps_;
  std::vector<OutgoingSeqNoJump> outgoing_seq_num_jumps_;
  std::vector<OutgoingCaptureTimeJump> outgoing_capture_time_jumps_;
  std::vector<OutgoingHighLoss> outgoing_high_loss_alerts_;

  std::map<uint32_t, std::string> candidate_pair_desc_by_id_;

  AnalyzerConfig config_;
};

}  // namespace webrtc

#endif  // RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_H_
