/*
 *  Copyright (c) 2014 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 <string>

#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/md5_helper.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif

namespace {

#if CONFIG_WEBM_IO

const int kLegacyByteAlignment = 0;
const int kLegacyYPlaneByteAlignment = 32;
const int kNumPlanesToCheck = 3;
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";

struct ByteAlignmentTestParam {
  int byte_alignment;
  vpx_codec_err_t expected_value;
  bool decode_remaining;
};

const ByteAlignmentTestParam kBaTestParams[] = {
  { kLegacyByteAlignment, VPX_CODEC_OK, true },
  { 32, VPX_CODEC_OK, true },
  { 64, VPX_CODEC_OK, true },
  { 128, VPX_CODEC_OK, true },
  { 256, VPX_CODEC_OK, true },
  { 512, VPX_CODEC_OK, true },
  { 1024, VPX_CODEC_OK, true },
  { 1, VPX_CODEC_INVALID_PARAM, false },
  { -2, VPX_CODEC_INVALID_PARAM, false },
  { 4, VPX_CODEC_INVALID_PARAM, false },
  { 16, VPX_CODEC_INVALID_PARAM, false },
  { 255, VPX_CODEC_INVALID_PARAM, false },
  { 2048, VPX_CODEC_INVALID_PARAM, false },
};

// Class for testing byte alignment of reference buffers.
class ByteAlignmentTest
    : public ::testing::TestWithParam<ByteAlignmentTestParam> {
 protected:
  ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {}

  virtual void SetUp() {
    video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
    ASSERT_TRUE(video_ != NULL);
    video_->Init();
    video_->Begin();

    const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
    decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
    ASSERT_TRUE(decoder_ != NULL);

    OpenMd5File(kVP9Md5File);
  }

  virtual void TearDown() {
    if (md5_file_ != NULL) fclose(md5_file_);

    delete decoder_;
    delete video_;
  }

  void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) {
    decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value);
  }

  vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) {
    const vpx_codec_err_t res =
        decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
    CheckDecodedFrames(byte_alignment_to_check);
    if (res == VPX_CODEC_OK) video_->Next();
    return res;
  }

  vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) {
    for (; video_->cxdata() != NULL; video_->Next()) {
      const vpx_codec_err_t res =
          decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
      if (res != VPX_CODEC_OK) return res;
      CheckDecodedFrames(byte_alignment_to_check);
    }
    return VPX_CODEC_OK;
  }

 private:
  // Check if |data| is aligned to |byte_alignment_to_check|.
  // |byte_alignment_to_check| must be a power of 2.
  void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) {
    ASSERT_EQ(0u, reinterpret_cast<size_t>(data) % byte_alignment_to_check);
  }

  // Iterate through the planes of the decoded frames and check for
  // alignment based off |byte_alignment_to_check|.
  void CheckDecodedFrames(int byte_alignment_to_check) {
    libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
    const vpx_image_t *img;

    // Get decompressed data
    while ((img = dec_iter.Next()) != NULL) {
      if (byte_alignment_to_check == kLegacyByteAlignment) {
        CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment);
      } else {
        for (int i = 0; i < kNumPlanesToCheck; ++i) {
          CheckByteAlignment(img->planes[i], byte_alignment_to_check);
        }
      }
      CheckMd5(*img);
    }
  }

  // TODO(fgalligan): Move the MD5 testing code into another class.
  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_;
  }

  void CheckMd5(const vpx_image_t &img) {
    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(EOF, res) << "Read md5 data failed";
    expected_md5[32] = '\0';

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

    // Check md5 match.
    ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match";
  }

  libvpx_test::WebMVideoSource *video_;
  libvpx_test::VP9Decoder *decoder_;
  FILE *md5_file_;
};

TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
  const int num_elements = 14;
  const int byte_alignments[] = { 0, 32,   64, 128, 256, 512, 1024,
                                  0, 1024, 32, 512, 64,  256, 128 };

  for (int i = 0; i < num_elements; ++i) {
    SetByteAlignment(byte_alignments[i], VPX_CODEC_OK);
    ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i]));
  }
  SetByteAlignment(byte_alignments[0], VPX_CODEC_OK);
  ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0]));
}

TEST_P(ByteAlignmentTest, TestAlignment) {
  const ByteAlignmentTestParam t = GetParam();
  SetByteAlignment(t.byte_alignment, t.expected_value);
  if (t.decode_remaining) {
    ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
  }
}

INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,
                        ::testing::ValuesIn(kBaTestParams));

#endif  // CONFIG_WEBM_IO

}  // namespace
