/*
 *  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 "rtc_tools/converter/converter.h"

#include <stdio.h>
#include <sys/stat.h>

#include <iomanip>
#include <sstream>

#include "third_party/libyuv/include/libyuv/compare.h"
#include "third_party/libyuv/include/libyuv/convert.h"

#ifdef WIN32
#define SEPARATOR '\\'
#define STAT _stat
#else
#define SEPARATOR '/'
#define STAT stat
#endif

namespace webrtc {
namespace test {

Converter::Converter(int width, int height) : width_(width), height_(height) {}

bool Converter::ConvertRGBAToI420Video(std::string frames_dir,
                                       std::string output_file_name,
                                       bool delete_frames) {
  FILE* output_file = fopen(output_file_name.c_str(), "wb");

  // Open output file in append mode.
  if (output_file == NULL) {
    fprintf(stderr, "Couldn't open input file for reading: %s\n",
            output_file_name.c_str());
    return false;
  }

  int input_frame_size = InputFrameSize();
  uint8_t* rgba_buffer = new uint8_t[input_frame_size];
  int y_plane_size = YPlaneSize();
  uint8_t* dst_y = new uint8_t[y_plane_size];
  int u_plane_size = UPlaneSize();
  uint8_t* dst_u = new uint8_t[u_plane_size];
  int v_plane_size = VPlaneSize();
  uint8_t* dst_v = new uint8_t[v_plane_size];

  int counter = 0;       // Counter to form frame names.
  bool success = false;  // Is conversion successful.

  while (true) {
    std::string file_name = FormFrameName(4, counter);
    // Get full path file name.
    std::string input_file_name = FindFullFileName(frames_dir, file_name);

    if (FileExists(input_file_name)) {
      ++counter;  // Update counter for the next round.
    } else {
      fprintf(stdout, "Reached end of frames list\n");
      break;
    }

    // Read the RGBA frame into rgba_buffer.
    ReadRGBAFrame(input_file_name.c_str(), input_frame_size, rgba_buffer);

    // Delete the input frame.
    if (delete_frames) {
      if (remove(input_file_name.c_str()) != 0) {
        fprintf(stderr, "Cannot delete file %s\n", input_file_name.c_str());
      }
    }

    // Convert to I420 frame.
    libyuv::ABGRToI420(rgba_buffer, SrcStrideFrame(), dst_y, DstStrideY(),
                       dst_u, DstStrideU(), dst_v, DstStrideV(), width_,
                       height_);

    // Add the I420 frame to the YUV video file.
    success = AddYUVToFile(dst_y, y_plane_size, dst_u, u_plane_size, dst_v,
                           v_plane_size, output_file);

    if (!success) {
      fprintf(stderr, "LibYUV error during RGBA to I420 frame conversion\n");
      break;
    }
  }

  delete[] rgba_buffer;
  delete[] dst_y;
  delete[] dst_u;
  delete[] dst_v;

  fclose(output_file);

  return success;
}

bool Converter::AddYUVToFile(uint8_t* y_plane,
                             int y_plane_size,
                             uint8_t* u_plane,
                             int u_plane_size,
                             uint8_t* v_plane,
                             int v_plane_size,
                             FILE* output_file) {
  bool success = AddYUVPlaneToFile(y_plane, y_plane_size, output_file) &&
                 AddYUVPlaneToFile(u_plane, u_plane_size, output_file) &&
                 AddYUVPlaneToFile(v_plane, v_plane_size, output_file);
  return success;
}

bool Converter::AddYUVPlaneToFile(uint8_t* yuv_plane,
                                  int yuv_plane_size,
                                  FILE* file) {
  size_t bytes_written = fwrite(yuv_plane, 1, yuv_plane_size, file);

  if (bytes_written != static_cast<size_t>(yuv_plane_size)) {
    fprintf(stderr,
            "Number of bytes written (%d) doesn't match size of y plane"
            " (%d)\n",
            static_cast<int>(bytes_written), yuv_plane_size);
    return false;
  }
  return true;
}

bool Converter::ReadRGBAFrame(const char* input_file_name,
                              int input_frame_size,
                              unsigned char* buffer) {
  FILE* input_file = fopen(input_file_name, "rb");
  if (input_file == NULL) {
    fprintf(stderr, "Couldn't open input file for reading: %s\n",
            input_file_name);
    return false;
  }

  size_t nbr_read = fread(buffer, 1, input_frame_size, input_file);
  fclose(input_file);

  if (nbr_read != static_cast<size_t>(input_frame_size)) {
    fprintf(stderr, "Error reading from input file: %s\n", input_file_name);
    return false;
  }

  return true;
}

std::string Converter::FindFullFileName(std::string dir_name,
                                        std::string file_name) {
  return dir_name + SEPARATOR + file_name;
}

bool Converter::FileExists(std::string file_name_to_check) {
  struct STAT file_info;
  int result = STAT(file_name_to_check.c_str(), &file_info);
  return (result == 0);
}

std::string Converter::FormFrameName(int width, int number) {
  std::stringstream tmp;

  // Zero-pad number to a string.
  tmp << std::setfill('0') << std::setw(width) << number;

  return "frame_" + tmp.str();
}

}  // namespace test
}  // namespace webrtc
