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

#include <cstdio>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/flags/usage.h"
#include "absl/flags/usage_config.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/units/time_delta.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_tools/rtc_event_log_visualizer/alerts.h"
#include "rtc_tools/rtc_event_log_visualizer/analyzer.h"
#include "rtc_tools/rtc_event_log_visualizer/analyzer_common.h"
#include "rtc_tools/rtc_event_log_visualizer/conversational_speech_en.h"
#include "rtc_tools/rtc_event_log_visualizer/plot_base.h"
#include "rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h"

ABSL_FLAG(std::string,
          plot,
          "default",
          "A comma separated list of plot names. See --list_plots for valid "
          "options.");

ABSL_FLAG(
    std::string,
    force_fieldtrials,
    "",
    "Field trials control experimental feature code which can be forced. "
    "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enabled/"
    " will assign the group Enabled to field trial WebRTC-FooFeature. Multiple "
    "trials are separated by \"/\"");
ABSL_FLAG(std::string,
          wav_filename,
          "",
          "Path to wav file used for simulation of jitter buffer.");

ABSL_FLAG(bool,
          show_detector_state,
          false,
          "Show the state of the delay based BWE detector on the total "
          "bitrate graph.");

ABSL_FLAG(bool,
          show_alr_state,
          false,
          "Show the state ALR state on the total bitrate graph.");

ABSL_FLAG(bool,
          show_link_capacity,
          true,
          "Show the lower and upper link capacity on the outgoing bitrate "
          "graph.");

ABSL_FLAG(bool,
          parse_unconfigured_header_extensions,
          true,
          "Attempt to parse unconfigured header extensions using the default "
          "WebRTC mapping. This can give very misleading results if the "
          "application negotiates a different mapping.");

ABSL_FLAG(bool,
          print_triage_alerts,
          true,
          "Print triage alerts, i.e. a list of potential problems.");

ABSL_FLAG(bool,
          normalize_time,
          true,
          "Normalize the log timestamps so that the call starts at time 0.");

ABSL_FLAG(bool,
          shared_xaxis,
          false,
          "Share x-axis between all plots so that zooming in one plot "
          "updates all the others too. A downside is that certain "
          "operations like panning become much slower.");

ABSL_FLAG(bool, show_grid, false, "Show a grid in all plots.");

ABSL_FLAG(bool,
          protobuf_output,
          false,
          "Output charts as protobuf instead of python code.");

ABSL_FLAG(std::string,
          figure_output_path,
          "",
          "A path to output the python plots into.");

ABSL_FLAG(bool,
          list_plots,
          false,
          "List of registered plots (for use with the --plot flag).");

ABSL_FLAG(int,
          averaging_window,
          250,
          "Time window (in ms) used for calculating moving average bitrates.");

ABSL_FLAG(int,
          averaging_step,
          10,
          "How often (in ms) a data point is generated in bitrate plots.");

ABSL_FLAG(
    bool,
    include_overhead,
    true,
    "Include estimated network-level protocol (IP/UDP/SRTP/STUN) overhead "
    "in the total incoming and outgoing bitrate graphs. This flag only "
    "affects incoming_bitrate and outgoing_bitrate graphs.");

namespace {
std::vector<std::string> StrSplit(const std::string& s,
                                  const std::string& delimiter) {
  std::vector<std::string> v;
  size_t pos = 0;
  while (pos < s.length()) {
    const std::string token = s.substr(pos, s.find(delimiter, pos) - pos);
    pos += token.length() + delimiter.length();
    v.push_back(token);
  }
  return v;
}

bool KnownPlotName(absl::string_view name,
                   const std::vector<std::string>& known_plots) {
  return absl::c_find(known_plots, name) != known_plots.end();
}

bool ContainsHelppackageFlags(absl::string_view filename) {
  return absl::EndsWith(filename, "main.cc");
}

}  // namespace

int main(int argc, char* argv[]) {
  absl::SetProgramUsageMessage(
      "A tool for visualizing WebRTC event logs.\n"
      "Example usage:\n"
      "./event_log_visualizer <logfile> | python\n");
  absl::FlagsUsageConfig flag_config;
  flag_config.contains_help_flags = &ContainsHelppackageFlags;
  absl::SetFlagsUsageConfig(flag_config);
  std::vector<char*> args = absl::ParseCommandLine(argc, argv);

  // Print RTC_LOG warnings and errors even in release builds.
  webrtc::LoggingConfig logging_config;
  logging_config.set_min_severity(webrtc::LS_WARNING);
  logging_config.set_debug_severity(webrtc::LS_WARNING);
  webrtc::InitializeLogging(std::move(logging_config));

  const std::string field_trials = absl::GetFlag(FLAGS_force_fieldtrials);
  webrtc::Environment env = webrtc::CreateEnvironment(
      std::make_unique<webrtc::FieldTrials>(field_trials));

  webrtc::ParsedRtcEventLog::UnconfiguredHeaderExtensions header_extensions =
      webrtc::ParsedRtcEventLog::UnconfiguredHeaderExtensions::kDontParse;
  if (absl::GetFlag(FLAGS_parse_unconfigured_header_extensions)) {
    header_extensions = webrtc::ParsedRtcEventLog::
        UnconfiguredHeaderExtensions::kAttemptWebrtcDefaultConfig;
  }
  webrtc::ParsedRtcEventLog parsed_log(header_extensions,
                                       /*allow_incomplete_logs*/ true);

  if (args.size() == 2) {
    std::string filename = args[1];
    auto status = parsed_log.ParseFile(filename);
    if (!status.ok()) {
      std::cerr << "Failed to parse " << filename << ": " << status.message()
                << std::endl;
      return -1;
    }
  }

  webrtc::AnalyzerConfig config(env, parsed_log,
                                absl::GetFlag(FLAGS_normalize_time));
  config.window_duration_ =
      webrtc::TimeDelta::Millis(absl::GetFlag(FLAGS_averaging_window));
  config.step_ = webrtc::TimeDelta::Millis(absl::GetFlag(FLAGS_averaging_step));
  if (config.end_time_ < config.begin_time_) {
    RTC_LOG(LS_WARNING) << "Log end time " << config.end_time_
                        << " not after begin time " << config.begin_time_
                        << ". Nothing to analyze. Is the log broken?";
    return -1;
  }

  std::string wav_path;
  bool has_generated_wav_file = false;
  if (!absl::GetFlag(FLAGS_wav_filename).empty()) {
    wav_path = absl::GetFlag(FLAGS_wav_filename);
  } else {
    // TODO(bugs.webrtc.org/14248): Remove the need to generate a file
    // and read the file directly from memory.
    wav_path = std::tmpnam(nullptr);
    std::ofstream out_wav_file(wav_path);
    out_wav_file.write(
        reinterpret_cast<char*>(&webrtc::conversational_speech_en_wav[0]),
        webrtc::conversational_speech_en_wav_len);
    has_generated_wav_file = true;
  }

  webrtc::EventLogAnalyzer analyzer(parsed_log, config);
  analyzer.InitializeMapOfNamedGraphs(absl::GetFlag(FLAGS_show_detector_state),
                                      absl::GetFlag(FLAGS_show_alr_state),
                                      absl::GetFlag(FLAGS_show_link_capacity),
                                      absl::GetFlag(FLAGS_include_overhead));
  analyzer.SetNetEqReplacementFile(wav_path, 48000);

  // Flag replacements
  std::map<std::string, std::vector<std::string>> flag_aliases = {
      {"default",
       {"incoming_delay", "incoming_loss_rate", "incoming_bitrate",
        "outgoing_bitrate", "incoming_stream_bitrate",
        "outgoing_stream_bitrate", "network_delay_feedback",
        "fraction_loss_feedback"}},
      {"sendside_bwe",
       {"outgoing_packet_sizes", "outgoing_bitrate", "outgoing_stream_bitrate",
        "simulated_sendside_bwe", "network_delay_feedback",
        "fraction_loss_feedback", "outgoing_twcc_loss"}},
      {"receiveside_bwe",
       {"incoming_packet_sizes", "incoming_delay", "incoming_loss_rate",
        "incoming_bitrate", "incoming_stream_bitrate",
        "simulated_receiveside_bwe"}},
      {"rtcp_details",
       {"incoming_rtcp_fraction_lost", "outgoing_rtcp_fraction_lost",
        "incoming_rtcp_cumulative_lost", "outgoing_rtcp_cumulative_lost",
        "incoming_rtcp_highest_seq_number", "outgoing_rtcp_highest_seq_number",
        "incoming_rtcp_delay_since_last_sr",
        "outgoing_rtcp_delay_since_last_sr"}},
      {"simulated_neteq_stats",
       {"simulated_neteq_jitter_buffer_delay",
        "simulated_neteq_preferred_buffer_size",
        "simulated_neteq_concealment_events", "simulated_neteq_preemptive_rate",
        "simulated_neteq_accelerate_rate", "simulated_neteq_speech_expand_rate",
        "simulated_neteq_expand_rate"}},
      {"l4s",
       {"incoming_bitrate", "outgoing_bitrate", "incoming_ecn_feedback",
        "outgoing_ecn_feedback"}},
      {"scream",
       {"scream_ref_window", "simulated_scream_delay",
        "simulated_scream_bitrates", "simulated_scream_ref_window",
        "simulated_scream_ratios", "simulated_scream_feedback_events_per_rtt",
        "network_delay_feedback", "pacer_delay"}}};

  if (absl::GetFlag(FLAGS_list_plots)) {
    std::cerr << "List of registered plots (for use with the --plot flag):"
              << std::endl;
    for (const auto& plot_name : analyzer.GetGraphNames()) {
      // TODO(terelius): Also print a help text.
      std::cerr << "  " << plot_name;
    }

    std::cerr << "List of plot aliases (for use with the --plot flag):"
              << std::endl;
    std::cerr << "  all = every registered plot" << std::endl;
    for (const auto& alias : flag_aliases) {
      std::cerr << "  " << alias.first << " = ";
      for (const auto& replacement : alias.second) {
        std::cerr << replacement << ",";
      }
      std::cerr << std::endl;
    }
    return 0;
  }

  if (args.size() != 2) {
    // Print usage information.
    std::cerr << absl::ProgramUsageMessage();
    return 1;
  }

  // Select which plots to output
  std::vector<std::string> plot_flags =
      StrSplit(absl::GetFlag(FLAGS_plot), ",");
  std::vector<std::string> plot_names;
  const std::vector<std::string> all_known_plots = analyzer.GetGraphNames();
  for (const std::string& flag : plot_flags) {
    if (flag == "all") {
      plot_names = all_known_plots;
      break;
    }
    auto alias_it = flag_aliases.find(flag);
    if (alias_it != flag_aliases.end()) {
      for (std::string& replacement : alias_it->second) {
        if (!KnownPlotName(replacement, all_known_plots)) {
          std::cerr << "Unknown plot name \"" << replacement << "\""
                    << std::endl;
          return 1;
        }
        plot_names.push_back(replacement);
      }
    } else {
      plot_names.push_back(flag);
      if (!KnownPlotName(flag, all_known_plots)) {
        std::cerr << "Unknown plot name \"" << flag << "\"" << std::endl;
        return 1;
      }
    }
  }

  webrtc::PlotCollection collection;
  analyzer.CreateGraphsByName(plot_names, &collection);

  collection.SetCallTimeToUtcOffsetMs(config.CallTimeToUtcOffsetMs());

  if (absl::GetFlag(FLAGS_protobuf_output)) {
    webrtc::analytics::ChartCollection proto_charts;
    collection.ExportProtobuf(&proto_charts);
    std::cout << proto_charts.SerializeAsString();
  } else {
    collection.PrintPythonCode(absl::GetFlag(FLAGS_shared_xaxis),
                               absl::GetFlag(FLAGS_show_grid),
                               absl::GetFlag(FLAGS_figure_output_path));
  }

  if (absl::GetFlag(FLAGS_print_triage_alerts)) {
    webrtc::TriageHelper triage_alerts(config);
    triage_alerts.AnalyzeLog(parsed_log);
    triage_alerts.Print(stderr);
  }

  // TODO(bugs.webrtc.org/14248): Remove the need to generate a file
  // and read the file directly from memory.
  if (has_generated_wav_file) {
    RTC_CHECK_EQ(std::remove(wav_path.c_str()), 0)
        << "Failed to remove " << wav_path;
  }
  return 0;
}
