/*
 *  Copyright (c) 2013 The WebM 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 <cstdio>
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "../tools_common.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
#include "test/md5_helper.h"
#include "test/test_vectors.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
#include "vpx_mem/vpx_mem.h"

namespace {

enum DecodeMode {
  kSerialMode,
  kFrameParallMode
};

const int kDecodeMode = 0;
const int kThreads = 1;
const int kFileName = 2;

typedef std::tr1::tuple<int, int, const char*> DecodeParam;

class TestVectorTest : public ::libvpx_test::DecoderTest,
    public ::libvpx_test::CodecTestWithParam<DecodeParam> {
 protected:
  TestVectorTest()
      : DecoderTest(GET_PARAM(0)),
        md5_file_(NULL) {
  }

  virtual ~TestVectorTest() {
    if (md5_file_)
      fclose(md5_file_);
  }

  void OpenMD5File(const std::string& md5_file_name_) {
    md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
    ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
        << md5_file_name_;
  }

  virtual void DecompressedFrameHook(const vpx_image_t& img,
                                     const unsigned int frame_number) {
    ASSERT_TRUE(md5_file_ != NULL);
    char expected_md5[33];
    char junk[128];

    // Read correct md5 checksums.
    const int res = fscanf(md5_file_, "%s  %s", expected_md5, junk);
    ASSERT_NE(res, EOF) << "Read md5 data failed";
    expected_md5[32] = '\0';

    ::libvpx_test::MD5 md5_res;
    md5_res.Add(&img);
    const char *actual_md5 = md5_res.Get();

    // Check md5 match.
    ASSERT_STREQ(expected_md5, actual_md5)
        << "Md5 checksums don't match: frame number = " << frame_number;
  }

 private:
  FILE *md5_file_;
};

// This test runs through the whole set of test vectors, and decodes them.
// The md5 checksums are computed for each frame in the video file. If md5
// checksums match the correct md5 data, then the test is passed. Otherwise,
// the test failed.
TEST_P(TestVectorTest, MD5Match) {
  const DecodeParam input = GET_PARAM(1);
  const std::string filename = std::tr1::get<kFileName>(input);
  const int threads = std::tr1::get<kThreads>(input);
  const int mode = std::tr1::get<kDecodeMode>(input);
  libvpx_test::CompressedVideoSource *video = NULL;
  vpx_codec_flags_t flags = 0;
  vpx_codec_dec_cfg_t cfg = {0};
  char str[256];

  if (mode == kFrameParallMode) {
    flags |= VPX_CODEC_USE_FRAME_THREADING;
  }

  cfg.threads = threads;

  snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
           "file: %s  mode: %s threads: %d",
           filename.c_str(), mode == 0 ? "Serial" : "Parallel", threads);
  SCOPED_TRACE(str);

  // Open compressed video file.
  if (filename.substr(filename.length() - 3, 3) == "ivf") {
    video = new libvpx_test::IVFVideoSource(filename);
  } else if (filename.substr(filename.length() - 4, 4) == "webm") {
#if CONFIG_WEBM_IO
    video = new libvpx_test::WebMVideoSource(filename);
#else
    fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
            filename.c_str());
    return;
#endif
  }
  video->Init();

  // Construct md5 file name.
  const std::string md5_filename = filename + ".md5";
  OpenMD5File(md5_filename);

  // Set decode config and flags.
  set_cfg(cfg);
  set_flags(flags);

  // Decode frame, and check the md5 matching.
  ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
  delete video;
}

// Test VP8 decode in serial mode with single thread.
// NOTE: VP8 only support serial mode.
INSTANTIATE_TEST_CASE_P(
    VP8, TestVectorTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
        ::testing::Combine(
            ::testing::Values(0),  // Serial Mode.
            ::testing::Values(1),  // Single thread.
            ::testing::ValuesIn(libvpx_test::kVP8TestVectors,
                                libvpx_test::kVP8TestVectors +
                                    libvpx_test::kNumVP8TestVectors))));

// Test VP9 decode in serial mode with single thread.
INSTANTIATE_TEST_CASE_P(
    VP9, TestVectorTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
        ::testing::Combine(
            ::testing::Values(0),  // Serial Mode.
            ::testing::Values(1),  // Single thread.
            ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
                                libvpx_test::kVP9TestVectors +
                                    libvpx_test::kNumVP9TestVectors))));


// Test VP9 decode in frame parallel mode with different number of threads.
INSTANTIATE_TEST_CASE_P(
    VP9MultiThreadedFrameParallel, TestVectorTest,
    ::testing::Combine(
        ::testing::Values(
            static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
        ::testing::Combine(
            ::testing::Values(1),        // Frame Parallel mode.
            ::testing::Range(2, 9),      // With 2 ~ 8 threads.
            ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
                                libvpx_test::kVP9TestVectors +
                                    libvpx_test::kNumVP9TestVectors))));
}  // namespace
