/*
 *  Copyright (c) 2012 The WebRTC 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.
 */

// Use CreateHistUnittestFile.m to generate the input file.

#include "modules/audio_processing/agc/loudness_histogram.h"

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <memory>
#include <string>

#include "absl/strings/string_view.h"
#include "modules/audio_processing/agc/utility.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

struct InputOutput {
  double rms;
  double activity_probability;
  double audio_content;
  double loudness;
};

constexpr double kRelativeErrTol = 1e-10;

class LoudnessHistogramTest : public ::testing::Test {
 protected:
  void RunTest(bool enable_circular_buff, absl::string_view filename);

 private:
  void TestClean();
  std::unique_ptr<LoudnessHistogram> hist_;
};

void LoudnessHistogramTest::TestClean() {
  EXPECT_EQ(hist_->CurrentRms(), 7.59621091765857e-02);
  EXPECT_EQ(hist_->AudioContent(), 0);
  EXPECT_EQ(hist_->num_updates(), 0);
}

void LoudnessHistogramTest::RunTest(bool enable_circular_buff,
                                    absl::string_view filename) {
  FILE* in_file = fopen(std::string(filename).c_str(), "rb");
  ASSERT_TRUE(in_file != nullptr);
  if (enable_circular_buff) {
    int buffer_size;
    EXPECT_EQ(fread(&buffer_size, sizeof(buffer_size), 1, in_file), 1u);
    hist_.reset(LoudnessHistogram::Create(buffer_size));
  } else {
    hist_.reset(LoudnessHistogram::Create());
  }
  TestClean();

  InputOutput io;
  int num_updates = 0;
  while (fread(&io, sizeof(InputOutput), 1, in_file) == 1) {
    if (io.rms < 0) {
      // We have to reset.
      hist_->Reset();
      TestClean();
      num_updates = 0;
      // Read the next chunk of input.
      if (fread(&io, sizeof(InputOutput), 1, in_file) != 1)
        break;
    }
    hist_->Update(io.rms, io.activity_probability);
    num_updates++;
    EXPECT_EQ(hist_->num_updates(), num_updates);
    double audio_content = hist_->AudioContent();

    double abs_err =
        std::min(audio_content, io.audio_content) * kRelativeErrTol;

    ASSERT_NEAR(audio_content, io.audio_content, abs_err);
    double current_loudness = Linear2Loudness(hist_->CurrentRms());
    abs_err =
        std::min(fabs(current_loudness), fabs(io.loudness)) * kRelativeErrTol;
    ASSERT_NEAR(current_loudness, io.loudness, abs_err);
  }
  fclose(in_file);
}

TEST_F(LoudnessHistogramTest, ActiveCircularBuffer) {
  RunTest(true, test::ResourcePath(
                    "audio_processing/agc/agc_with_circular_buffer", "dat")
                    .c_str());
}

TEST_F(LoudnessHistogramTest, InactiveCircularBuffer) {
  RunTest(false, test::ResourcePath(
                     "audio_processing/agc/agc_no_circular_buffer", "dat")
                     .c_str());
}

}  // namespace webrtc
