/*
 *  Copyright (c) 2013 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.
 */

#include "webrtc/modules/audio_processing/transient/wpd_tree.h"

#include <sstream>
#include <string>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_processing/transient/daubechies_8_wavelet_coeffs.h"
#include "webrtc/modules/audio_processing/transient/file_utils.h"
#include "webrtc/system_wrappers/interface/file_wrapper.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/gtest_disable.h"

namespace webrtc {

TEST(WPDTreeTest, Construction) {
  const size_t kTestBufferSize = 100;
  const int kLevels = 5;
  const int kExpectedNumberOfNodes = (1 << (kLevels + 1)) - 1;

  float test_buffer[kTestBufferSize];
  memset(test_buffer, 0.f, kTestBufferSize * sizeof(*test_buffer));
  float test_coefficients[] = {1.f, 2.f, 3.f, 4.f, 5.f};
  const size_t kTestCoefficientsLength = sizeof(test_coefficients) /
      sizeof(test_coefficients[0]);
  WPDTree tree(kTestBufferSize,
               test_coefficients,
               test_coefficients,
               kTestCoefficientsLength,
               kLevels);
  ASSERT_EQ(kExpectedNumberOfNodes, tree.num_nodes());
  // Checks for NodeAt(level, index).
  int nodes_at_level = 0;
  for (int level = 0; level <= kLevels; ++level) {
    nodes_at_level = 1 << level;
    for (int i = 0; i < nodes_at_level; ++i) {
      ASSERT_TRUE(NULL != tree.NodeAt(level, i));
    }
    // Out of bounds.
    EXPECT_EQ(NULL, tree.NodeAt(level, -1));
    EXPECT_EQ(NULL, tree.NodeAt(level, -12));
    EXPECT_EQ(NULL, tree.NodeAt(level, nodes_at_level));
    EXPECT_EQ(NULL, tree.NodeAt(level, nodes_at_level + 5));
  }
  // Out of bounds.
  EXPECT_EQ(NULL, tree.NodeAt(-1, 0));
  EXPECT_EQ(NULL, tree.NodeAt(-12, 0));
  EXPECT_EQ(NULL, tree.NodeAt(kLevels + 1, 0));
  EXPECT_EQ(NULL, tree.NodeAt(kLevels + 5, 0));
  // Checks for Update().
  EXPECT_EQ(0, tree.Update(test_buffer, kTestBufferSize));
  EXPECT_EQ(-1, tree.Update(NULL, kTestBufferSize));
  EXPECT_EQ(-1, tree.Update(test_buffer, kTestBufferSize - 1));
}

// This test is for the correctness of the tree.
// Checks the results from the Matlab equivalent, it is done comparing the
// results that are stored in the output files from Matlab.
// It also writes the results in its own set of files in the out directory.
// Matlab and output files contain all the results in double precision (Little
// endian) appended.
TEST(WPDTreeTest, DISABLED_ON_IOS(CorrectnessBasedOnMatlabFiles)) {
  // 10 ms at 16000 Hz.
  const size_t kTestBufferSize = 160;
  const int kLevels = 3;
  const int kLeaves = 1 << kLevels;
  const size_t kLeavesSamples = kTestBufferSize >> kLevels;
  // Create tree with Discrete Meyer Wavelet Coefficients.
  WPDTree tree(kTestBufferSize,
               kDaubechies8HighPassCoefficients,
               kDaubechies8LowPassCoefficients,
               kDaubechies8CoefficientsLength,
               kLevels);
  // Allocate and open all matlab and out files.
  rtc::scoped_ptr<FileWrapper> matlab_files_data[kLeaves];
  rtc::scoped_ptr<FileWrapper> out_files_data[kLeaves];

  for (int i = 0; i < kLeaves; ++i) {
    // Matlab files.
    matlab_files_data[i].reset(FileWrapper::Create());

    std::ostringstream matlab_stream;
    matlab_stream << "audio_processing/transient/wpd" << i;
    std::string matlab_string = test::ResourcePath(matlab_stream.str(), "dat");
    matlab_files_data[i]->OpenFile(matlab_string.c_str(),
                                   true,    // Read only.
                                   false,   // No loop.
                                   false);  // No text.

    bool file_opened = matlab_files_data[i]->Open();
    ASSERT_TRUE(file_opened) << "File could not be opened.\n" << matlab_string;

    // Out files.
    out_files_data[i].reset(FileWrapper::Create());

    std::ostringstream out_stream;
    out_stream << test::OutputPath() << "wpd_" << i << ".out";
    std::string out_string = out_stream.str();

    out_files_data[i]->OpenFile(out_string.c_str(),
                                false,    // Write mode.
                                false,    // No loop.
                                false);   // No text.

    file_opened = out_files_data[i]->Open();
    ASSERT_TRUE(file_opened) << "File could not be opened.\n" << out_string;
  }

  // Prepare the test file.
  std::string test_file_name = test::ResourcePath(
      "audio_processing/transient/ajm-macbook-1-spke16m", "pcm");

  rtc::scoped_ptr<FileWrapper> test_file(FileWrapper::Create());

  test_file->OpenFile(test_file_name.c_str(),
                      true,    // Read only.
                      false,   // No loop.
                      false);  // No text.

  bool file_opened = test_file->Open();
  ASSERT_TRUE(file_opened) << "File could not be opened.\n" << test_file_name;

  float test_buffer[kTestBufferSize];

  // Only the first frames of the audio file are tested. The matlab files also
  // only contains information about the first frames.
  const size_t kMaxFramesToTest = 100;
  const float kTolerance = 0.03f;

  size_t frames_read = 0;

  // Read first buffer from the PCM test file.
  size_t file_samples_read = ReadInt16FromFileToFloatBuffer(test_file.get(),
                                                            kTestBufferSize,
                                                            test_buffer);
  while (file_samples_read > 0 && frames_read < kMaxFramesToTest) {
    ++frames_read;

    if (file_samples_read < kTestBufferSize) {
      // Pad the rest of the buffer with zeros.
      for (size_t i = file_samples_read; i < kTestBufferSize; ++i) {
        test_buffer[i] = 0.0;
      }
    }
    tree.Update(test_buffer, kTestBufferSize);
    double matlab_buffer[kTestBufferSize];

    // Compare results with data from the matlab test files.
    for (int i = 0; i < kLeaves; ++i) {
      // Compare data values
      size_t matlab_samples_read =
          ReadDoubleBufferFromFile(matlab_files_data[i].get(),
                                   kLeavesSamples,
                                   matlab_buffer);

      ASSERT_EQ(kLeavesSamples, matlab_samples_read)
          << "Matlab test files are malformed.\n"
          << "File: 3_" << i;
      // Get output data from the corresponding node
      const float* node_data = tree.NodeAt(kLevels, i)->data();
      // Compare with matlab files.
      for (size_t j = 0; j < kLeavesSamples; ++j) {
        EXPECT_NEAR(matlab_buffer[j], node_data[j], kTolerance)
            << "\nLeaf: " << i << "\nSample: " << j
            << "\nFrame: " << frames_read - 1;
      }

      // Write results to out files.
      WriteFloatBufferToFile(out_files_data[i].get(),
                             kLeavesSamples,
                             node_data);
    }

    // Read next buffer from the PCM test file.
    file_samples_read = ReadInt16FromFileToFloatBuffer(test_file.get(),
                                                       kTestBufferSize,
                                                       test_buffer);
  }

  // Close all matlab and out files.
  for (int i = 0; i < kLeaves; ++i) {
    matlab_files_data[i]->CloseFile();
    out_files_data[i]->CloseFile();
  }

  test_file->CloseFile();
}

}  // namespace webrtc
