/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#include "third_party/googletest/src/googletest/include/gtest/gtest.h"

#include <cstdlib>

#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"

#include "aom_dsp/entenc.h"
#include "aom_dsp/entdec.h"
#include "aom_dsp/prob.h"

TEST(EC_TEST, random_ec_test_Large) {
  od_ec_enc enc;
  od_ec_dec dec;
  int sz;
  int i;
  int ret;
  unsigned int seed;
  unsigned char *ptr;
  uint32_t ptr_sz;
  char *seed_str;
  ret = 0;
  seed_str = getenv("EC_TEST_SEED");
  if (seed_str) {
    seed = atoi(seed_str);
  } else {
    seed = 0xdaa1a;
  }
  srand(seed);
  od_ec_enc_init(&enc, 1);
  /*Test compatibility between multiple different encode/decode routines.*/
  for (i = 0; i < 409600; i++) {
    unsigned *fz;
    unsigned *fts;
    unsigned *data;
    unsigned *mode;
    unsigned long *tell;
    unsigned *enc_method;
    int j;
    sz = rand() / ((RAND_MAX >> (rand() % 9U)) + 1U);
    fz = (unsigned *)malloc(sz * sizeof(*fz));
    fts = (unsigned *)malloc(sz * sizeof(*fts));
    data = (unsigned *)malloc(sz * sizeof(*data));
    mode = (unsigned *)malloc(sz * sizeof(*mode));
    tell = (unsigned long *)malloc((sz + 1) * sizeof(*tell));
    enc_method = (unsigned *)malloc(sz * sizeof(*enc_method));
    od_ec_enc_reset(&enc);
    tell[0] = od_ec_enc_tell_frac(&enc);
    for (j = 0; j < sz; j++) {
      data[j] = rand();
      mode[j] = rand();

      fts[j] = CDF_PROB_BITS;
      fz[j] = (rand() % (CDF_PROB_TOP - 2)) >> (CDF_PROB_BITS - fts[j]);
      fz[j] = OD_MAXI(fz[j] & ~1, 2);
      enc_method[j] = 1 + (rand() & 3);
      switch (enc_method[j]) {
        case 1: {
          // Write literal in smaller pieces; read back in single call.
          int bits = (mode[j] & 7) + 1;
          data[j] &= ((1 << bits) - 1);
          int chunk = ((mode[j] >> 4) & 7) + 1;
          int d = data[j];
          while (bits > 0) {
            int n = bits > chunk ? chunk : bits;
            od_ec_encode_literal_bypass(&enc, (d >> (bits - n)), n);
            bits -= n;
            d &= ((1 << bits) - 1);
          }
          break;
        }
        case 2: {
          // Write literal in single call; read back in smaller pieces.
          int bits = (mode[j] & 7) + 1;
          data[j] &= ((1 << bits) - 1);
          od_ec_encode_literal_bypass(&enc, data[j], bits);
          break;
        }
        case 3: {
          data[j] &= 1;
          od_ec_encode_bool_bypass(&enc, data[j]);
          break;
        }
        case 4: {
          data[j] &= 1;
          uint16_t cdf[16] = {};
          cdf[0] = OD_ICDF(fz[j]);
          cdf[1] = OD_ICDF(1U << fts[j]);
          od_ec_encode_cdf_q15(&enc, data[j], cdf, 2);
          break;
        }
      }

      tell[j + 1] = od_ec_enc_tell_frac(&enc);
    }
    ptr = od_ec_enc_done(&enc, &ptr_sz);
    EXPECT_GE(((od_ec_enc_tell(&enc) + 7U) >> 3), ptr_sz)
        << "od_ec_enc_tell() lied: "
           "there's "
        << ptr_sz << " bytes instead of " << ((od_ec_enc_tell(&enc) + 7) >> 3)
        << " (Random seed: " << seed << ")\n";
    od_ec_dec_init(&dec, ptr, ptr_sz);
    EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[0])
        << "od_ec_dec_tell() mismatch between encoder and decoder "
           "at symbol 0: "
        << (unsigned long)od_ec_dec_tell_frac(&dec) << " instead of " << tell[0]
        << " (Random seed: " << seed << ").\n";
    for (j = 0; j < sz; j++) {
      int dec_method;
      unsigned int sym = data[j] + 1;  // Initialize sym to an invalid value.

      dec_method = enc_method[j];
      switch (dec_method) {
        case 1: {
          int bits = (mode[j] & 7) + 1;
          sym = od_ec_decode_literal_bypass(&dec, bits);
          break;
        }
        case 2: {
          int bits = (mode[j] & 7) + 1;
          int chunk = ((mode[j] >> 4) & 7) + 1;
          sym = 0;
          while (bits > 0) {
            int n = bits > chunk ? chunk : bits;
            sym <<= n;
            sym += od_ec_decode_literal_bypass(&dec, n);
            bits -= n;
          }
          break;
        }
        case 3: {
          sym = od_ec_decode_bool_bypass(&dec);
          break;
        }
        case 4: {
          uint16_t cdf[16] = {};
          cdf[0] = OD_ICDF(fz[j]);
          cdf[1] = OD_ICDF(1U << fts[j]);
          sym = od_ec_decode_cdf_q15(&dec, cdf, 2);
          break;
        }
      }

      EXPECT_EQ(sym, data[j])
          << "Decoded " << sym << " instead of " << data[j]
          << " with fz=" << fz[j] << " and ftb=" << fts[j] << "at position "
          << j << " of " << sz << " (Random seed: " << seed << ").\n"
          << "Encoding method: " << enc_method[j]
          << " decoding method: " << dec_method << "\n";
      EXPECT_EQ(od_ec_dec_tell_frac(&dec), tell[j + 1])
          << "od_ec_dec_tell() mismatch between encoder and "
             "decoder at symbol "
          << j + 1 << ": " << (unsigned long)od_ec_dec_tell_frac(&dec)
          << " instead of " << tell[j + 1] << " (Random seed: " << seed
          << ").\n";
    }
    free(enc_method);
    free(tell);
    free(mode);
    free(data);
    free(fts);
    free(fz);
  }
  od_ec_enc_reset(&enc);
  if (CDF_SHIFT == 0) {
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576));
    od_ec_enc_patch_initial_bits(&enc, 3, 2);
    EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
    od_ec_enc_patch_initial_bits(&enc, 0, 5);
    EXPECT_TRUE(enc.error)
        << "od_ec_enc_patch_initial_bits() didn't fail when it should have.\n";
    od_ec_enc_reset(&enc);
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_literal_bypass(&enc, 0, 1);
    od_ec_encode_bool_q15(&enc, 1, OD_ICDF(32256));
    od_ec_encode_bool_q15(&enc, 0, OD_ICDF(24576));
    od_ec_enc_patch_initial_bits(&enc, 0, 2);
    EXPECT_FALSE(enc.error) << "od_ec_enc_patch_initial_bits() failed.\n";
    ptr = od_ec_enc_done(&enc, &ptr_sz);
    EXPECT_EQ(ptr_sz, 2u);
    EXPECT_EQ(ptr[0], 63)
        << "Got " << ptr[0]
        << " when expecting 63 for od_ec_enc_patch_initial_bits().\n";
  }
  od_ec_enc_clear(&enc);
  EXPECT_EQ(ret, 0);
}
