/*
 *  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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <numeric>
#include <vector>

#include "rtc_tools/frame_analyzer/reference_less_video_analysis_lib.h"
#include "rtc_tools/frame_analyzer/video_quality_analysis.h"

#define STATS_LINE_LENGTH 28
#define PSNR_FREEZE_THRESHOLD 47
#define SSIM_FREEZE_THRESHOLD .999

#if defined(_WIN32) || defined(_WIN64)
#define strtok_r strtok_s
#endif

bool frozen_frame(std::vector<double> psnr_per_frame,
                  std::vector<double> ssim_per_frame,
                  size_t frame) {
  if (psnr_per_frame[frame] >= PSNR_FREEZE_THRESHOLD ||
      ssim_per_frame[frame] >= SSIM_FREEZE_THRESHOLD)
    return true;
  return false;
}

std::vector<int> find_frame_clusters(
    const std::vector<double>& psnr_per_frame,
    const std::vector<double>& ssim_per_frame) {
  std::vector<int> identical_frame_clusters;
  int num_frozen = 0;
  size_t total_no_of_frames = psnr_per_frame.size();

  for (size_t each_frame = 0; each_frame < total_no_of_frames; each_frame++) {
    if (frozen_frame(psnr_per_frame, ssim_per_frame, each_frame)) {
      num_frozen++;
    } else if (num_frozen > 0) {
      // Not frozen anymore.
      identical_frame_clusters.push_back(num_frozen);
      num_frozen = 0;
    }
  }
  return identical_frame_clusters;
}

void print_freezing_metrics(const std::vector<double>& psnr_per_frame,
                            const std::vector<double>& ssim_per_frame) {
  /*
   * Prints the different metrics mainly:
   * 1) Identical frame number, PSNR and SSIM values.
   * 2) Length of continuous frozen frames.
   * 3) Max length of continuous freezed frames.
   * 4) No of unique frames found.
   * 5) Total different identical frames found.
   *
   * Sample output:
   *  Printing metrics for file: /src/rtc_tools/test_3.y4m
      =============================
      Total number of frames received: 74
      Total identical frames: 5
      Number of unique frames: 69
      Printing Identical Frames:
        Frame Number: 29 PSNR: 48.000000 SSIM: 0.999618
        Frame Number: 30 PSNR: 48.000000 SSIM: 0.999898
        Frame Number: 60 PSNR: 48.000000 SSIM: 0.999564
        Frame Number: 64 PSNR: 48.000000 SSIM: 0.999651
        Frame Number: 69 PSNR: 48.000000 SSIM: 0.999684
      Print identical frame which appears in clusters :
        2 1 1 1
   *
   */
  size_t total_no_of_frames = psnr_per_frame.size();
  std::vector<int> identical_frame_clusters =
      find_frame_clusters(psnr_per_frame, ssim_per_frame);
  int total_identical_frames = std::accumulate(
      identical_frame_clusters.begin(), identical_frame_clusters.end(), 0);
  size_t unique_frames = total_no_of_frames - total_identical_frames;

  printf("Total number of frames received: %zu\n", total_no_of_frames);
  printf("Total identical frames: %d\n", total_identical_frames);
  printf("Number of unique frames: %zu\n", unique_frames);

  printf("Printing Identical Frames: \n");
  for (size_t frame = 0; frame < total_no_of_frames; frame++) {
    if (frozen_frame(psnr_per_frame, ssim_per_frame, frame)) {
      printf("  Frame Number: %zu PSNR: %f SSIM: %f \n", frame,
             psnr_per_frame[frame], ssim_per_frame[frame]);
    }
  }

  printf("Print identical frame which appears in clusters : \n");
  for (int cluster = 0;
       cluster < static_cast<int>(identical_frame_clusters.size()); cluster++)
    printf("%d ", identical_frame_clusters[cluster]);
  printf("\n");
}

void compute_metrics(const rtc::scoped_refptr<webrtc::test::Y4mFile>& video,
                     std::vector<double>* psnr_per_frame,
                     std::vector<double>* ssim_per_frame) {
  for (size_t i = 0; i < video->number_of_frames() - 1; ++i) {
    const rtc::scoped_refptr<webrtc::I420BufferInterface> current_frame =
        video->GetFrame(i);
    const rtc::scoped_refptr<webrtc::I420BufferInterface> next_frame =
        video->GetFrame(i + 1);
    double result_psnr = webrtc::test::Psnr(current_frame, next_frame);
    double result_ssim = webrtc::test::Ssim(current_frame, next_frame);

    psnr_per_frame->push_back(result_psnr);
    ssim_per_frame->push_back(result_ssim);
  }
}

int run_analysis(const std::string& video_file) {
  std::vector<double> psnr_per_frame;
  std::vector<double> ssim_per_frame;
  rtc::scoped_refptr<webrtc::test::Y4mFile> video =
      webrtc::test::Y4mFile::Open(video_file);
  if (video) {
    compute_metrics(video, &psnr_per_frame, &ssim_per_frame);
  } else {
    return -1;
  }
  printf("=============================\n");
  printf("Printing metrics for file: %s\n", video_file.c_str());
  printf("=============================\n");
  print_freezing_metrics(psnr_per_frame, ssim_per_frame);
  return 0;
}
