/*
 *  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_PLOT_BASE_H_
#define RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_PLOT_BASE_H_

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

#include "rtc_base/deprecation.h"
#include "rtc_base/ignore_wundef.h"

RTC_PUSH_IGNORING_WUNDEF()
#include "rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h"
RTC_POP_IGNORING_WUNDEF()

namespace webrtc {

enum class LineStyle {
  kNone,  // No line connecting the points. Used to create scatter plots.
  kLine,  // Straight line between consecutive points.
  kStep,  // Horizontal line until the next value. Used for state changes.
  kBar    // Vertical bars from the x-axis to the point.
};

enum class PointStyle {
  kNone,      // Don't draw the points.
  kHighlight  // Draw circles or dots to highlight the points.
};

struct TimeSeriesPoint {
  TimeSeriesPoint(float x, float y) : x(x), y(y) {}
  float x;
  float y;
};

struct TimeSeries {
  TimeSeries() = default;  // TODO(terelius): Remove the default constructor.
  TimeSeries(const char* label,
             LineStyle line_style,
             PointStyle point_style = PointStyle::kNone)
      : label(label), line_style(line_style), point_style(point_style) {}
  TimeSeries(const std::string& label,
             LineStyle line_style,
             PointStyle point_style = PointStyle::kNone)
      : label(label), line_style(line_style), point_style(point_style) {}
  TimeSeries(TimeSeries&& other)
      : label(std::move(other.label)),
        line_style(other.line_style),
        point_style(other.point_style),
        points(std::move(other.points)) {}
  TimeSeries& operator=(TimeSeries&& other) {
    label = std::move(other.label);
    line_style = other.line_style;
    point_style = other.point_style;
    points = std::move(other.points);
    return *this;
  }

  std::string label;
  LineStyle line_style = LineStyle::kLine;
  PointStyle point_style = PointStyle::kNone;
  std::vector<TimeSeriesPoint> points;
};

struct Interval {
  Interval() = default;
  Interval(double begin, double end) : begin(begin), end(end) {}

  double begin;
  double end;
};

struct IntervalSeries {
  enum Orientation { kHorizontal, kVertical };

  IntervalSeries() = default;
  IntervalSeries(const std::string& label,
                 const std::string& color,
                 IntervalSeries::Orientation orientation)
      : label(label), color(color), orientation(orientation) {}

  std::string label;
  std::string color;
  Orientation orientation;
  std::vector<Interval> intervals;
};

// A container that represents a general graph, with axes, title and one or
// more data series. A subclass should define the output format by overriding
// the Draw() method.
class Plot {
 public:
  virtual ~Plot() {}

  // Deprecated. Use PrintPythonCode() or ExportProtobuf() instead.
  RTC_DEPRECATED virtual void Draw() {}

  // Sets the lower x-axis limit to min_value (if left_margin == 0).
  // Sets the upper x-axis limit to max_value (if right_margin == 0).
  // The margins are measured as fractions of the interval
  // (max_value - min_value) and are added to either side of the plot.
  void SetXAxis(float min_value,
                float max_value,
                std::string label,
                float left_margin = 0,
                float right_margin = 0);

  // Sets the lower and upper x-axis limits based on min_value and max_value,
  // but modified such that all points in the data series can be represented
  // on the x-axis. The margins are measured as fractions of the range of
  // x-values and are added to either side of the plot.
  void SetSuggestedXAxis(float min_value,
                         float max_value,
                         std::string label,
                         float left_margin = 0,
                         float right_margin = 0);

  // Sets the lower y-axis limit to min_value (if bottom_margin == 0).
  // Sets the upper y-axis limit to max_value (if top_margin == 0).
  // The margins are measured as fractions of the interval
  // (max_value - min_value) and are added to either side of the plot.
  void SetYAxis(float min_value,
                float max_value,
                std::string label,
                float bottom_margin = 0,
                float top_margin = 0);

  // Sets the lower and upper y-axis limits based on min_value and max_value,
  // but modified such that all points in the data series can be represented
  // on the y-axis. The margins are measured as fractions of the range of
  // y-values and are added to either side of the plot.
  void SetSuggestedYAxis(float min_value,
                         float max_value,
                         std::string label,
                         float bottom_margin = 0,
                         float top_margin = 0);

  void SetYAxisTickLabels(
      const std::vector<std::pair<float, std::string>>& labels);

  // Sets the title of the plot.
  void SetTitle(const std::string& title);

  // Sets an unique ID for the plot. The ID is similar to the title except that
  // the title might change in future releases whereas the ID should be stable
  // over time.
  void SetId(const std::string& id);

  // Add a new TimeSeries to the plot.
  void AppendTimeSeries(TimeSeries&& time_series);

  // Add a new IntervalSeries to the plot.
  void AppendIntervalSeries(IntervalSeries&& interval_series);

  // Add a new TimeSeries to the plot if the series contains contains data.
  // Otherwise, the call has no effect and the timeseries is destroyed.
  void AppendTimeSeriesIfNotEmpty(TimeSeries&& time_series);

  // Replaces PythonPlot::Draw()
  void PrintPythonCode() const;

  // Replaces ProtobufPlot::Draw()
  void ExportProtobuf(webrtc::analytics::Chart* chart) const;

 protected:
  float xaxis_min_;
  float xaxis_max_;
  std::string xaxis_label_;
  float yaxis_min_;
  float yaxis_max_;
  std::string yaxis_label_;
  std::vector<std::pair<float, std::string>> yaxis_tick_labels_;
  std::string title_;
  std::string id_;
  std::vector<TimeSeries> series_list_;
  std::vector<IntervalSeries> interval_list_;
};

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

  // Deprecated. Use PrintPythonCode() or ExportProtobuf() instead.
  RTC_DEPRECATED virtual void Draw() {}

  virtual Plot* AppendNewPlot();

  // Replaces PythonPlotCollection::Draw()
  void PrintPythonCode(bool shared_xaxis) const;

  // Replaces ProtobufPlotCollections::Draw()
  void ExportProtobuf(webrtc::analytics::ChartCollection* collection) const;

 protected:
  std::vector<std::unique_ptr<Plot>> plots_;
};

}  // namespace webrtc

#endif  // RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_PLOT_BASE_H_
