/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <cstdio>
#include <string>

#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/ivf_video_source.h"
#include "test/util.h"
#include "test/video_source.h"

namespace {

struct DecodeParam {
  int threads;
  const char *filename;
  const char *res_filename;  // If NULL, the result filename is
                             // filename + ".res".
};

// Constructs result file name.
std::string GetResFilename(const DecodeParam &param) {
  if (param.res_filename != NULL) return param.res_filename;
  const std::string filename = param.filename;
  return filename + ".res";
}

std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
  return os << "threads: " << dp.threads << " file: " << dp.filename
            << " result file: " << GetResFilename(dp);
}

class InvalidFileTest : public ::libaom_test::DecoderTest,
                        public ::libaom_test::CodecTestWithParam<DecodeParam> {
 protected:
  InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}

  virtual ~InvalidFileTest() {
    if (res_file_ != NULL) fclose(res_file_);
  }

  void OpenResFile(const std::string &res_file_name) {
    res_file_ = libaom_test::OpenTestDataFile(res_file_name);
    ASSERT_TRUE(res_file_ != NULL)
        << "Result file open failed. Filename: " << res_file_name;
  }

  virtual void DecompressedFrameHook(const aom_image_t &img,
                                     const unsigned int /*frame_number*/) {
    EXPECT_NE(img.fb_priv, nullptr);
  }

  virtual bool HandleDecodeResult(
      const aom_codec_err_t res_dec,
      const libaom_test::CompressedVideoSource &video,
      libaom_test::Decoder *decoder) {
    EXPECT_TRUE(res_file_ != NULL);
    int expected_res_dec = -1;

    // Read integer result.
    const int res = fscanf(res_file_, "%d", &expected_res_dec);
    EXPECT_NE(res, EOF) << "Read result data failed";

    if (expected_res_dec != -1) {
      // Check results match.
      const DecodeParam input = GET_PARAM(1);
      if (input.threads > 1) {
        // The serial decode check is too strict for tile-threaded decoding as
        // there is no guarantee on the decode order nor which specific error
        // will take precedence. Currently a tile-level error is not forwarded
        // so the frame will simply be marked corrupt.
        EXPECT_TRUE(res_dec == expected_res_dec ||
                    res_dec == AOM_CODEC_CORRUPT_FRAME)
            << "Results don't match: frame number = " << video.frame_number()
            << ". (" << decoder->DecodeError()
            << "). Expected: " << expected_res_dec << " or "
            << AOM_CODEC_CORRUPT_FRAME;
      } else {
        EXPECT_EQ(expected_res_dec, res_dec)
            << "Results don't match: frame number = " << video.frame_number()
            << ". (" << decoder->DecodeError() << ")";
      }
    }

    return !HasFailure();
  }

  virtual void HandlePeekResult(libaom_test::Decoder *const /*decoder*/,
                                libaom_test::CompressedVideoSource * /*video*/,
                                const aom_codec_err_t /*res_peek*/) {}

  void RunTest() {
    const DecodeParam input = GET_PARAM(1);
    aom_codec_dec_cfg_t cfg = { 0, 0, 0, !FORCE_HIGHBITDEPTH_DECODING, { 1 } };
    cfg.threads = input.threads;
    const std::string filename = input.filename;
    libaom_test::IVFVideoSource decode_video(filename);
    decode_video.Init();

    // The result file holds a list of expected integer results, one for each
    // decoded frame.  Any result that doesn't match the file's list will
    // cause a test failure.
    const std::string res_filename = GetResFilename(input);
    OpenResFile(res_filename);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&decode_video, cfg));
  }

 private:
  FILE *res_file_;
};

TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }

// If res_filename (the third field) is NULL, then the result filename is
// filename + ".res" by default. Set res_filename to a string if the result
// filename differs from the default.
const DecodeParam kAV1InvalidFileTests[] = {
  // { threads, filename, res_filename }
  { 1, "invalid-bug-1814.ivf", NULL },
  { 1, "invalid-chromium-906381.ivf", NULL },
  { 4, "invalid-oss-fuzz-9463.ivf", NULL },
  { 1, "invalid-oss-fuzz-9720.ivf", NULL },
  { 1, "invalid-oss-fuzz-10389.ivf", NULL },
  { 1, "invalid-oss-fuzz-11523.ivf", "invalid-oss-fuzz-11523.ivf.res.2" },
  { 4, "invalid-oss-fuzz-15363.ivf", NULL },
  { 1, "invalid-oss-fuzz-16437.ivf", NULL },
#if CONFIG_AV1_HIGHBITDEPTH
  // These test vectors contain 10-bit or 12-bit video.
  { 1, "invalid-oss-fuzz-9288.ivf", NULL },
  { 1, "invalid-oss-fuzz-9482.ivf", NULL },
  { 1, "invalid-oss-fuzz-10061.ivf", NULL },
  { 1, "invalid-oss-fuzz-10117-mc-buf-use-highbd.ivf", NULL },
  { 1, "invalid-oss-fuzz-10227.ivf", NULL },
  { 4, "invalid-oss-fuzz-10555.ivf", NULL },
  { 1, "invalid-oss-fuzz-10705.ivf", NULL },
  { 1, "invalid-oss-fuzz-10723.ivf", NULL },
  { 1, "invalid-oss-fuzz-10779.ivf", NULL },
  { 1, "invalid-oss-fuzz-11477.ivf", NULL },
  { 1, "invalid-oss-fuzz-11479.ivf", "invalid-oss-fuzz-11479.ivf.res.2" },
#endif
};

AV1_INSTANTIATE_TEST_CASE(InvalidFileTest,
                          ::testing::ValuesIn(kAV1InvalidFileTests));

}  // namespace
