/*
 *  Copyright (c) 2023 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 "rtc_tools/rtc_event_log_visualizer/analyzer_bindings.h"

#include <cstddef>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>

#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "api/units/time_delta.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/protobuf_utils.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/plot_base.h"

#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
#include "external/webrtc/webrtc/rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h"
#else
#include "rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h"
#endif

using webrtc::PacketDirection;

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;
}
}  // namespace

void analyze_rtc_event_log(const char* log_contents,
                           size_t log_size,
                           const char* selection,
                           size_t selection_size,
                           char* output,
                           uint32_t* output_size) {
  webrtc::ParsedRtcEventLog parsed_log(
      webrtc::ParsedRtcEventLog::UnconfiguredHeaderExtensions::kDontParse,
      /*allow_incomplete_logs*/ false);

  absl::string_view log_view(log_contents, log_size);
  auto status = parsed_log.ParseString(log_view);
  if (!status.ok()) {
    std::cerr << "Failed to parse log: " << status.message() << std::endl;
    *output_size = 0;
    return;
  }

  webrtc::AnalyzerConfig config;
  config.window_duration_ = webrtc::TimeDelta::Millis(250);
  config.step_ = webrtc::TimeDelta::Millis(10);
  if (!parsed_log.start_log_events().empty()) {
    config.rtc_to_utc_offset_ = parsed_log.start_log_events()[0].utc_time() -
                                parsed_log.start_log_events()[0].log_time();
  }
  config.normalize_time_ = true;
  config.begin_time_ = parsed_log.first_timestamp();
  config.end_time_ = parsed_log.last_timestamp();
  if (config.end_time_ < config.begin_time_) {
    std::cerr << "Log end time " << config.end_time_.ms()
              << " not after begin time " << config.begin_time_.ms()
              << ". Nothing to analyze. Is the log broken?";
    *output_size = 0;
    return;
  }

  webrtc::EventLogAnalyzer analyzer(parsed_log, config);
  analyzer.InitializeMapOfNamedGraphs(/*show_detector_state=*/false,
                                      /*show_alr_state=*/false,
                                      /*show_link_capacity=*/false);

  webrtc::PlotCollection collection;
  std::vector<std::string> plot_names =
      StrSplit(std::string(selection, selection_size), ",");
  analyzer.CreateGraphsByName(plot_names, &collection);
  collection.SetCallTimeToUtcOffsetMs(config.CallTimeToUtcOffsetMs());

  webrtc::analytics::ChartCollection proto_charts;
  collection.ExportProtobuf(&proto_charts);
  std::string serialized_charts = proto_charts.SerializeAsString();
  if (rtc::checked_cast<uint32_t>(serialized_charts.size()) > *output_size) {
    std::cerr << "Serialized charts larger than available output buffer: "
              << serialized_charts.size() << " vs " << *output_size
              << std::endl;
    *output_size = 0;
    return;
  }

  memcpy(output, serialized_charts.data(), serialized_charts.size());
  *output_size = rtc::checked_cast<uint32_t>(serialized_charts.size());
}
