/*
 *  Copyright (c) 2014 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 <math.h>
#include <limits>

#include "webrtc/audio_processing/debug.pb.h"
#include "webrtc/common_audio/include/audio_util.h"
#include "webrtc/common_audio/wav_writer.h"
#include "webrtc/modules/audio_processing/common.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

static const AudioProcessing::Error kNoErr = AudioProcessing::kNoError;
#define EXPECT_NOERR(expr) EXPECT_EQ(kNoErr, (expr))

class RawFile {
 public:
  RawFile(const std::string& filename)
      : file_handle_(fopen(filename.c_str(), "wb")) {}

  ~RawFile() {
    fclose(file_handle_);
  }

  void WriteSamples(const int16_t* samples, size_t num_samples) {
#ifndef WEBRTC_ARCH_LITTLE_ENDIAN
#error "Need to convert samples to little-endian when writing to PCM file"
#endif
    fwrite(samples, sizeof(*samples), num_samples, file_handle_);
  }

  void WriteSamples(const float* samples, size_t num_samples) {
    fwrite(samples, sizeof(*samples), num_samples, file_handle_);
  }

 private:
  FILE* file_handle_;
};

static inline void WriteIntData(const int16_t* data,
                                size_t length,
                                WavFile* wav_file,
                                RawFile* raw_file) {
  if (wav_file) {
    wav_file->WriteSamples(data, length);
  }
  if (raw_file) {
    raw_file->WriteSamples(data, length);
  }
}

static inline void WriteFloatData(const float* const* data,
                                  size_t samples_per_channel,
                                  int num_channels,
                                  WavFile* wav_file,
                                  RawFile* raw_file) {
  size_t length = num_channels * samples_per_channel;
  scoped_ptr<float[]> buffer(new float[length]);
  Interleave(data, samples_per_channel, num_channels, buffer.get());
  if (raw_file) {
    raw_file->WriteSamples(buffer.get(), length);
  }
  // TODO(aluebs): Use ScaleToInt16Range() from audio_util
  for (size_t i = 0; i < length; ++i) {
    buffer[i] = buffer[i] > 0 ?
                buffer[i] * std::numeric_limits<int16_t>::max() :
                -buffer[i] * std::numeric_limits<int16_t>::min();
  }
  if (wav_file) {
    wav_file->WriteSamples(buffer.get(), length);
  }
}

// Exits on failure; do not use in unit tests.
static inline FILE* OpenFile(const std::string& filename, const char* mode) {
  FILE* file = fopen(filename.c_str(), mode);
  if (!file) {
    printf("Unable to open file %s\n", filename.c_str());
    exit(1);
  }
  return file;
}

static inline int SamplesFromRate(int rate) {
  return AudioProcessing::kChunkSizeMs * rate / 1000;
}

static inline void SetFrameSampleRate(AudioFrame* frame,
                                      int sample_rate_hz) {
  frame->sample_rate_hz_ = sample_rate_hz;
  frame->samples_per_channel_ = AudioProcessing::kChunkSizeMs *
      sample_rate_hz / 1000;
}

template <typename T>
void SetContainerFormat(int sample_rate_hz,
                        int num_channels,
                        AudioFrame* frame,
                        scoped_ptr<ChannelBuffer<T> >* cb) {
  SetFrameSampleRate(frame, sample_rate_hz);
  frame->num_channels_ = num_channels;
  cb->reset(new ChannelBuffer<T>(frame->samples_per_channel_, num_channels));
}

static inline AudioProcessing::ChannelLayout LayoutFromChannels(
    int num_channels) {
  switch (num_channels) {
    case 1:
      return AudioProcessing::kMono;
    case 2:
      return AudioProcessing::kStereo;
    default:
      assert(false);
      return AudioProcessing::kMono;
  }
}

// Allocates new memory in the scoped_ptr to fit the raw message and returns the
// number of bytes read.
static inline size_t ReadMessageBytesFromFile(FILE* file,
                                              scoped_ptr<uint8_t[]>* bytes) {
  // The "wire format" for the size is little-endian. Assume we're running on
  // a little-endian machine.
  int32_t size = 0;
  if (fread(&size, sizeof(size), 1, file) != 1)
    return 0;
  if (size <= 0)
    return 0;

  bytes->reset(new uint8_t[size]);
  return fread(bytes->get(), sizeof((*bytes)[0]), size, file);
}

// Returns true on success, false on error or end-of-file.
static inline bool ReadMessageFromFile(FILE* file,
                                       ::google::protobuf::MessageLite* msg) {
  scoped_ptr<uint8_t[]> bytes;
  size_t size = ReadMessageBytesFromFile(file, &bytes);
  if (!size)
    return false;

  msg->Clear();
  return msg->ParseFromArray(bytes.get(), size);
}

template <typename T>
float ComputeSNR(const T* ref, const T* test, int length, float* variance) {
  float mse = 0;
  float mean = 0;
  *variance = 0;
  for (int i = 0; i < length; ++i) {
    T error = ref[i] - test[i];
    mse += error * error;
    *variance += ref[i] * ref[i];
    mean += ref[i];
  }
  mse /= length;
  *variance /= length;
  mean /= length;
  *variance -= mean * mean;

  float snr = 100;  // We assign 100 dB to the zero-error case.
  if (mse > 0)
    snr = 10 * log10(*variance / mse);
  return snr;
}

}  // namespace webrtc
