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

void get_height_width_fps(int *height, int *width, int *fps,
                          const std::string& video_file) {
  // File header looks like :
  //  YUV4MPEG2 W1280 H720 F25:1 Ip A0:0 C420mpeg2 XYSCSS=420MPEG2.
  char frame_header[STATS_LINE_LENGTH];
  FILE* input_file = fopen(video_file.c_str(), "rb");

  size_t bytes_read = fread(frame_header, 1, STATS_LINE_LENGTH - 1, input_file);

  frame_header[bytes_read] = '\0';
  std::string file_header_stats[5];
  int no_of_stats = 0;
  char *save_ptr;
  char *token = strtok_r(frame_header, " ", &save_ptr);

  while (token != NULL) {
    file_header_stats[no_of_stats++] = token;
    token = strtok_r(NULL, " ", &save_ptr);
  }

  *width = std::stoi(file_header_stats[1].erase(0, 1));
  *height = std::stoi(file_header_stats[2].erase(0, 1));
  *fps = std::stoi(file_header_stats[3].erase(0, 1));

  printf("Height: %d Width: %d fps:%d \n", *height, *width, *fps);
  fclose(input_file);
}

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 std::string& video_file_name,
                     std::vector<double>* psnr_per_frame,
                     std::vector<double>* ssim_per_frame) {
  int height = 0, width = 0, fps = 0;
  get_height_width_fps(&height, &width, &fps, video_file_name);

  int no_of_frames = 0;
  int size = webrtc::test::GetI420FrameSize(width, height);

  // Allocate buffers for test and reference frames.
  uint8_t* current_frame = new uint8_t[size];
  uint8_t* next_frame = new uint8_t[size];

  while (true) {
    if (!(webrtc::test::ExtractFrameFromY4mFile (video_file_name.c_str(),
                                                 width, height,
                                                 no_of_frames,
                                                 current_frame))) {
      break;
    }

    if (!(webrtc::test::ExtractFrameFromY4mFile (video_file_name.c_str(),
                                                 width, height,
                                                 no_of_frames + 1,
                                                 next_frame))) {
      break;
    }

    double result_psnr = webrtc::test::CalculateMetrics(webrtc::test::kPSNR,
                                                        current_frame,
                                                        next_frame,
                                                        width, height);
    double result_ssim = webrtc::test::CalculateMetrics(webrtc::test::kSSIM,
                                                        current_frame,
                                                        next_frame,
                                                        width, height);

    psnr_per_frame->push_back(result_psnr);
    ssim_per_frame->push_back(result_ssim);
    no_of_frames++;
  }
  // Cleanup.
  delete[] current_frame;
  delete[] next_frame;
}

bool check_file_extension(const std::string& video_file_name) {
  if (video_file_name.substr(video_file_name.length()-3, 3) != "y4m") {
    printf("Only y4m video file format is supported. Given: %s\n",
           video_file_name.c_str());
    return false;
  }
  return true;
}

int run_analysis(const std::string& video_file) {
  std::vector<double> psnr_per_frame;
  std::vector<double> ssim_per_frame;
  if (check_file_extension(video_file)) {
    compute_metrics(video_file, &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;
}
