/*
 *  Copyright (c) 2012 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 <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/match.h"
#include "api/scoped_refptr.h"
#include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h"
#include "api/test/metrics/global_metrics_logger_and_exporter.h"
#include "api/test/metrics/metric.h"
#include "api/test/metrics/metrics_exporter.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_tools/frame_analyzer/video_color_aligner.h"
#include "rtc_tools/frame_analyzer/video_geometry_aligner.h"
#include "rtc_tools/frame_analyzer/video_quality_analysis.h"
#include "rtc_tools/frame_analyzer/video_temporal_aligner.h"
#include "rtc_tools/video_file_reader.h"
#include "rtc_tools/video_file_writer.h"

ABSL_FLAG(int32_t, width, -1, "The width of the reference and test files");
ABSL_FLAG(int32_t, height, -1, "The height of the reference and test files");
ABSL_FLAG(std::string,
          label,
          "MY_TEST",
          "The label to use for the perf output");
ABSL_FLAG(std::string,
          reference_file,
          "ref.yuv",
          "The reference YUV file to run the analysis against");
ABSL_FLAG(std::string,
          test_file,
          "test.yuv",
          "The test YUV file to run the analysis for");
ABSL_FLAG(std::string,
          aligned_output_file,
          "",
          "Where to write aligned YUV/Y4M output file, f not present, no files "
          "will be written");
ABSL_FLAG(std::string,
          yuv_directory,
          "",
          "Where to write aligned YUV ref+test output files, if not present, "
          "no files will be written");
ABSL_FLAG(std::string,
          chartjson_result_file,
          "",
          "Where to store perf result in chartjson format, if not present, no "
          "perf result will be stored");

namespace {

#ifdef WIN32
const char* const kPathDelimiter = "\\";
#else
const char* const kPathDelimiter = "/";
#endif

std::string JoinFilename(std::string directory, std::string filename) {
  return directory + kPathDelimiter + filename;
}

// FrameAnalyzerMetricsExporter is a fork of
// webrtc::test::StdoutMetricsExporter. The fork was required because:
// 1. frame_analyzer must be compiled with build_with_chromium=true
// 2. The api/metrics:stdout_metrics_exporter depends on absl/flags which cannot
//    be build when build_with_chromium=true unless the target is an
//    rtc_executable (which is not the case for
//    api/metrics:stdout_metrics_exporter). So this fork allows to cut the
//    dependency.

// Returns positive integral part of the number.
int64_t IntegralPart(double value) {
  return std::lround(std::floor(std::abs(value)));
}

void AppendWithPrecision(double value,
                         int digits_after_comma,
                         webrtc::StringBuilder& out) {
  int64_t multiplier = std::lround(std::pow(10, digits_after_comma));
  int64_t integral_part = IntegralPart(value);
  double decimal_part = std::abs(value) - integral_part;

  // If decimal part has leading zeros then when it will be multiplied on
  // `multiplier`, leading zeros will be lost. To preserve them we add "1"
  // so then leading digit will be greater than 0 and won't be removed.
  //
  // During conversion to the string leading digit has to be stripped.
  //
  // Also due to rounding it may happen that leading digit may be incremented,
  // like with `digits_after_comma` 3 number 1.9995 will be rounded to 2. In
  // such case this increment has to be propagated to the `integral_part`.
  int64_t decimal_holder = std::lround((1 + decimal_part) * multiplier);
  if (decimal_holder >= 2 * multiplier) {
    // Rounding incremented added leading digit, so we need to transfer 1 to
    // integral part.
    integral_part++;
    decimal_holder -= multiplier;
  }
  // Remove trailing zeros.
  while (decimal_holder % 10 == 0) {
    decimal_holder /= 10;
  }

  // Print serialized number to output.
  if (value < 0) {
    out << "-";
  }
  out << integral_part;
  if (decimal_holder != 1) {
    out << "." << std::to_string(decimal_holder).substr(1, digits_after_comma);
  }
}

class FrameAnalyzerMetricsExporter : public webrtc::test::MetricsExporter {
 public:
  FrameAnalyzerMetricsExporter() : output_(stdout) {}
  ~FrameAnalyzerMetricsExporter() override = default;

  FrameAnalyzerMetricsExporter(const FrameAnalyzerMetricsExporter&) = delete;
  FrameAnalyzerMetricsExporter& operator=(const FrameAnalyzerMetricsExporter&) =
      delete;

  bool Export(std::span<const webrtc::test::Metric> metrics) override {
    for (const webrtc::test::Metric& metric : metrics) {
      PrintMetric(metric);
    }
    return true;
  }

 private:
  void PrintMetric(const webrtc::test::Metric& metric) {
    webrtc::StringBuilder value_stream;
    value_stream << metric.test_case << " / " << metric.name << "= {mean=";
    if (metric.stats.mean.has_value()) {
      AppendWithPrecision(*metric.stats.mean, 8, value_stream);
    } else {
      value_stream << "-";
    }
    value_stream << ", stddev=";
    if (metric.stats.stddev.has_value()) {
      AppendWithPrecision(*metric.stats.stddev, 8, value_stream);
    } else {
      value_stream << "-";
    }
    value_stream << "} " << ToString(metric.unit) << " ("
                 << ToString(metric.improvement_direction) << ")";

    fprintf(output_, "RESULT: %s\n", value_stream.Release().c_str());
  }

  FILE* const output_;
};

}  // namespace

/*
 * A command line tool running PSNR and SSIM on a reference video and a test
 * video. The test video is a record of the reference video which can start at
 * an arbitrary point. It is possible that there will be repeated frames or
 * skipped frames as well. The video files should be I420 .y4m or .yuv videos.
 * If both files are .y4m, it's not needed to specify width/height. The tool
 * prints the result to standard output in the Chromium perf format:
 * RESULT <metric>:<label>= <values>
 *
 * The max value for PSNR is 48.0 (between equal frames), as for SSIM it is 1.0.
 *
 * Usage:
 * frame_analyzer --label=<test_label> --reference_file=<name_of_file>
 * --test_file_ref=<name_of_file> --width=<frame_width> --height=<frame_height>
 */
int main(int argc, char* argv[]) {
  absl::ParseCommandLine(argc, argv);

  int width = absl::GetFlag(FLAGS_width);
  int height = absl::GetFlag(FLAGS_height);
  const std::string reference_file_name = absl::GetFlag(FLAGS_reference_file);
  const std::string test_file_name = absl::GetFlag(FLAGS_test_file);

  // .yuv files require explicit resolution.
  if ((absl::EndsWith(reference_file_name, ".yuv") ||
       absl::EndsWith(test_file_name, ".yuv")) &&
      (width <= 0 || height <= 0)) {
    fprintf(stderr,
            "Error: You need to specify width and height when using .yuv "
            "files\n");
    return -1;
  }

  webrtc::test::ResultsContainer results;

  webrtc::scoped_refptr<webrtc::test::Video> reference_video =
      webrtc::test::OpenYuvOrY4mFile(reference_file_name, width, height);
  webrtc::scoped_refptr<webrtc::test::Video> test_video =
      webrtc::test::OpenYuvOrY4mFile(test_file_name, width, height);

  if (!reference_video || !test_video) {
    fprintf(stderr, "Error opening video files\n");
    return 1;
  }

  const std::vector<size_t> matching_indices =
      webrtc::test::FindMatchingFrameIndices(reference_video, test_video);

  // Align the reference video both temporally and geometrically. I.e. align the
  // frames to match up in order to the test video, and align a crop region of
  // the reference video to match up to the test video.
  const webrtc::scoped_refptr<webrtc::test::Video> aligned_reference_video =
      AdjustCropping(ReorderVideo(reference_video, matching_indices),
                     test_video);

  // Calculate if there is any systematic color difference between the reference
  // and test video.
  const webrtc::test::ColorTransformationMatrix color_transformation =
      CalculateColorTransformationMatrix(aligned_reference_video, test_video);

  webrtc::StringBuilder string_builder;
  for (int i = 0; i < 3; ++i) {
    string_builder << "\n";
    for (int j = 0; j < 4; ++j)
      string_builder.AppendFormat("%6.2f ", color_transformation[i][j]);
  }
  printf("Adjusting test video with color transformation: %s\n",
         string_builder.Release().c_str());

  // Adjust all frames in the test video with the calculated color
  // transformation.
  const webrtc::scoped_refptr<webrtc::test::Video> color_adjusted_test_video =
      AdjustColors(color_transformation, test_video);

  results.frames = webrtc::test::RunAnalysis(
      aligned_reference_video, color_adjusted_test_video, matching_indices);

  const std::vector<webrtc::test::Cluster> clusters =
      webrtc::test::CalculateFrameClusters(matching_indices);
  results.max_repeated_frames = webrtc::test::GetMaxRepeatedFrames(clusters);
  results.max_skipped_frames = webrtc::test::GetMaxSkippedFrames(clusters);
  results.total_skipped_frames =
      webrtc::test::GetTotalNumberOfSkippedFrames(clusters);
  results.decode_errors_ref = 0;
  results.decode_errors_test = 0;

  webrtc::test::PrintAnalysisResults(absl::GetFlag(FLAGS_label), results,
                                     *webrtc::test::GetGlobalMetricsLogger());

  std::vector<std::unique_ptr<webrtc::test::MetricsExporter>> exporters;
  exporters.push_back(std::make_unique<FrameAnalyzerMetricsExporter>());
  std::string chartjson_result_file =
      absl::GetFlag(FLAGS_chartjson_result_file);
  if (!chartjson_result_file.empty()) {
    exporters.push_back(
        std::make_unique<webrtc::test::ChromePerfDashboardMetricsExporter>(
            chartjson_result_file));
  }
  if (!webrtc::test::ExportPerfMetric(*webrtc::test::GetGlobalMetricsLogger(),
                                      std::move(exporters))) {
    return 1;
  }
  std::string aligned_output_file = absl::GetFlag(FLAGS_aligned_output_file);
  if (!aligned_output_file.empty()) {
    webrtc::test::WriteVideoToFile(aligned_reference_video, aligned_output_file,
                                   /*fps=*/30);
  }
  std::string yuv_directory = absl::GetFlag(FLAGS_yuv_directory);
  if (!yuv_directory.empty()) {
    webrtc::test::WriteVideoToFile(aligned_reference_video,
                                   JoinFilename(yuv_directory, "ref.yuv"),
                                   /*fps=*/30);
    webrtc::test::WriteVideoToFile(color_adjusted_test_video,
                                   JoinFilename(yuv_directory, "test.yuv"),
                                   /*fps=*/30);
  }

  return 0;
}
