/*
 * 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 <vector>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
#include "test/acm_random.h"

#include "./aom_config.h"

#include "aom_ports/mem.h"  // ROUND_POWER_OF_TWO
#include "aom/aomcx.h"
#include "aom/aomdx.h"
#include "aom/aom_encoder.h"
#include "aom/aom_decoder.h"

using libaom_test::ACMRandom;
namespace {

class CompressedSource {
 public:
  explicit CompressedSource(int seed) : rnd_(seed), frame_count_(0) {
    aom_codec_iface_t *algo = aom_codec_av1_cx();

    aom_codec_enc_cfg_t cfg;
    aom_codec_enc_config_default(algo, &cfg, 0);

    // force the quantizer, to reduce the sensitivity on encoding choices.
    // e.g, we don't want this test to break when the rate control is modified.
    {
      const int max_q = cfg.rc_max_quantizer;
      const int min_q = cfg.rc_min_quantizer;
      const int q = rnd_.PseudoUniform(max_q - min_q + 1) + min_q;

      cfg.rc_end_usage = AOM_Q;
      cfg.rc_max_quantizer = q;
      cfg.rc_min_quantizer = q;
    }

    // choose the picture size
    {
      width_ = rnd_.PseudoUniform(kWidth - 8) + 8;
      height_ = rnd_.PseudoUniform(kHeight - 8) + 8;
    }

    // choose the chroma subsampling
    {
      const aom_img_fmt_t fmts[] = {
        AOM_IMG_FMT_I420,
        AOM_IMG_FMT_I422,
        AOM_IMG_FMT_I444,
      };

      format_ = fmts[rnd_.PseudoUniform(NELEMENTS(fmts))];
    }

    cfg.g_w = width_;
    cfg.g_h = height_;
    cfg.g_lag_in_frames = 0;
    if (format_ == AOM_IMG_FMT_I420)
      cfg.g_profile = 0;
    else if (format_ == AOM_IMG_FMT_I444)
      cfg.g_profile = 1;
    else if (format_ == AOM_IMG_FMT_I422)
      cfg.g_profile = 2;

    aom_codec_enc_init(&enc_, algo, &cfg, 0);
  }

  ~CompressedSource() { aom_codec_destroy(&enc_); }

  const aom_codec_cx_pkt_t *ReadFrame() {
    uint8_t buf[kWidth * kHeight * 3] = { 0 };

    // render regular pattern
    const int period = rnd_.Rand8() % 32 + 1;
    const int phase = rnd_.Rand8() % period;

    const int val_a = rnd_.Rand8();
    const int val_b = rnd_.Rand8();

    for (int i = 0; i < (int)sizeof buf; ++i)
      buf[i] = (i + phase) % period < period / 2 ? val_a : val_b;

    aom_image_t img;
    aom_img_wrap(&img, format_, width_, height_, 0, buf);
    aom_codec_encode(&enc_, &img, frame_count_++, 1, 0);

    aom_codec_iter_t iter = NULL;

    const aom_codec_cx_pkt_t *pkt = NULL;

    do {
      pkt = aom_codec_get_cx_data(&enc_, &iter);
    } while (pkt && pkt->kind != AOM_CODEC_CX_FRAME_PKT);

    return pkt;
  }

 private:
  static const int kWidth = 128;
  static const int kHeight = 128;

  ACMRandom rnd_;
  aom_img_fmt_t format_;
  aom_codec_ctx_t enc_;
  int frame_count_;
  int width_, height_;
};

// lowers an aom_image_t to a easily comparable/printable form
std::vector<int16_t> Serialize(const aom_image_t *img) {
  std::vector<int16_t> bytes;
  bytes.reserve(img->d_w * img->d_h * 3);
  for (int plane = 0; plane < 3; ++plane) {
    const int w = aom_img_plane_width(img, plane);
    const int h = aom_img_plane_height(img, plane);

    for (int r = 0; r < h; ++r) {
      for (int c = 0; c < w; ++c) {
        unsigned char *row = img->planes[plane] + r * img->stride[plane];
        if (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH)
          bytes.push_back(row[c * 2]);
        else
          bytes.push_back(row[c]);
      }
    }
  }

  return bytes;
}

class Decoder {
 public:
  explicit Decoder(int allowLowbitdepth) {
    aom_codec_iface_t *algo = aom_codec_av1_dx();

    aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
    cfg.allow_lowbitdepth = allowLowbitdepth;

    aom_codec_dec_init(&dec_, algo, &cfg, 0);
  }

  ~Decoder() { aom_codec_destroy(&dec_); }

  std::vector<int16_t> decode(const aom_codec_cx_pkt_t *pkt) {
    aom_codec_decode(&dec_, static_cast<uint8_t *>(pkt->data.frame.buf),
                     static_cast<unsigned int>(pkt->data.frame.sz), NULL);

    aom_codec_iter_t iter = NULL;
    return Serialize(aom_codec_get_frame(&dec_, &iter));
  }

 private:
  aom_codec_ctx_t dec_;
};

// Try to reveal a mismatch between LBD and HBD coding paths.
TEST(CodingPathSync, SearchForHbdLbdMismatch) {
  const int count_tests = 10;
  for (int i = 0; i < count_tests; ++i) {
    Decoder dec_hbd(0);
    Decoder dec_lbd(1);

    CompressedSource enc(i);

    for (int k = 0; k < 3; ++k) {
      const aom_codec_cx_pkt_t *frame = enc.ReadFrame();

      std::vector<int16_t> lbd_yuv = dec_lbd.decode(frame);
      std::vector<int16_t> hbd_yuv = dec_hbd.decode(frame);

      ASSERT_EQ(lbd_yuv, hbd_yuv);
    }
  }
}

TEST(CodingPathSyncLarge, SearchForHbdLbdMismatchLarge) {
  const int count_tests = 100;
  const int seed = 1234;
  for (int i = 0; i < count_tests; ++i) {
    Decoder dec_hbd(0);
    Decoder dec_lbd(1);

    CompressedSource enc(seed + i);

    for (int k = 0; k < 5; ++k) {
      const aom_codec_cx_pkt_t *frame = enc.ReadFrame();

      std::vector<int16_t> lbd_yuv = dec_lbd.decode(frame);
      std::vector<int16_t> hbd_yuv = dec_hbd.decode(frame);

      ASSERT_EQ(lbd_yuv, hbd_yuv);
    }
  }
}

}  // namespace
