/*
 *  Copyright (c) 2015 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 <queue>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/format_macros.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/voice_engine/test/auto_test/fakes/conference_transport.h"

namespace {
const int kRttMs = 25;

bool IsNear(int ref, int comp, int error) {
  return (ref - comp <= error) && (comp - ref >= -error);
}

void CreateSilenceFile(const std::string& silence_file, int sample_rate_hz) {
  FILE* fid = fopen(silence_file.c_str(), "wb");
  int16_t zero = 0;
  for (int i = 0; i < sample_rate_hz; ++i) {
    // Write 1 second, but it does not matter since the file will be looped.
    fwrite(&zero, sizeof(int16_t), 1, fid);
  }
  fclose(fid);
}

}  // namespace

namespace voetest {

TEST(VoeConferenceTest, RttAndStartNtpTime) {
  struct Stats {
    Stats(int64_t rtt_receiver_1, int64_t rtt_receiver_2, int64_t ntp_delay)
        : rtt_receiver_1_(rtt_receiver_1),
          rtt_receiver_2_(rtt_receiver_2),
          ntp_delay_(ntp_delay) {
    }
    int64_t rtt_receiver_1_;
    int64_t rtt_receiver_2_;
    int64_t ntp_delay_;
  };

  const std::string input_file =
      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
  const webrtc::FileFormats kInputFormat = webrtc::kFileFormatPcm32kHzFile;

  const int kDelayMs = 987;
  ConferenceTransport trans;
  trans.SetRtt(kRttMs);

  unsigned int id_1 = trans.AddStream(input_file, kInputFormat);
  unsigned int id_2 = trans.AddStream(input_file, kInputFormat);

  EXPECT_TRUE(trans.StartPlayout(id_1));
  // Start NTP time is the time when a stream is played out, rather than
  // when it is added.
  webrtc::SleepMs(kDelayMs);
  EXPECT_TRUE(trans.StartPlayout(id_2));

  const int kMaxRunTimeMs = 25000;
  const int kNeedSuccessivePass = 3;
  const int kStatsRequestIntervalMs = 1000;
  const int kStatsBufferSize = 3;

  uint32_t deadline = rtc::TimeAfter(kMaxRunTimeMs);
  // Run the following up to |kMaxRunTimeMs| milliseconds.
  int successive_pass = 0;
  webrtc::CallStatistics stats_1;
  webrtc::CallStatistics stats_2;
  std::queue<Stats> stats_buffer;

  while (rtc::TimeIsLater(rtc::Time(), deadline) &&
      successive_pass < kNeedSuccessivePass) {
    webrtc::SleepMs(kStatsRequestIntervalMs);

    EXPECT_TRUE(trans.GetReceiverStatistics(id_1, &stats_1));
    EXPECT_TRUE(trans.GetReceiverStatistics(id_2, &stats_2));

    // It is not easy to verify the NTP time directly. We verify it by testing
    // the difference of two start NTP times.
    int64_t captured_start_ntp_delay = stats_2.capture_start_ntp_time_ms_ -
        stats_1.capture_start_ntp_time_ms_;

    // For the checks of RTT and start NTP time, We allow 10% accuracy.
    if (IsNear(kRttMs, stats_1.rttMs, kRttMs / 10 + 1) &&
        IsNear(kRttMs, stats_2.rttMs, kRttMs / 10 + 1) &&
        IsNear(kDelayMs, captured_start_ntp_delay, kDelayMs / 10 + 1)) {
      successive_pass++;
    } else {
      successive_pass = 0;
    }
    if (stats_buffer.size() >= kStatsBufferSize) {
      stats_buffer.pop();
    }
    stats_buffer.push(Stats(stats_1.rttMs, stats_2.rttMs,
                            captured_start_ntp_delay));
  }

  EXPECT_GE(successive_pass, kNeedSuccessivePass) << "Expected to get RTT and"
      " start NTP time estimate within 10% of the correct value over "
      << kStatsRequestIntervalMs * kNeedSuccessivePass / 1000
      << " seconds.";
  if (successive_pass < kNeedSuccessivePass) {
    printf("The most recent values (RTT for receiver 1, RTT for receiver 2, "
        "NTP delay between receiver 1 and 2) are (from oldest):\n");
    while (!stats_buffer.empty()) {
      Stats stats = stats_buffer.front();
      printf("(%" PRId64 ", %" PRId64 ", %" PRId64 ")\n", stats.rtt_receiver_1_,
             stats.rtt_receiver_2_, stats.ntp_delay_);
      stats_buffer.pop();
    }
  }
}


TEST(VoeConferenceTest, ReceivedPackets) {
  const int kPackets = 50;
  const int kPacketDurationMs = 20;  // Correspond to Opus.

  const std::string input_file =
      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
  const webrtc::FileFormats kInputFormat = webrtc::kFileFormatPcm32kHzFile;

  const std::string silence_file =
      webrtc::test::TempFilename(webrtc::test::OutputPath(), "silence");
  CreateSilenceFile(silence_file, 32000);

  {
    ConferenceTransport trans;
    // Add silence to stream 0, so that it will be filtered out.
    unsigned int id_0 = trans.AddStream(silence_file, kInputFormat);
    unsigned int id_1 = trans.AddStream(input_file, kInputFormat);
    unsigned int id_2 = trans.AddStream(input_file, kInputFormat);
    unsigned int id_3 = trans.AddStream(input_file, kInputFormat);

    EXPECT_TRUE(trans.StartPlayout(id_0));
    EXPECT_TRUE(trans.StartPlayout(id_1));
    EXPECT_TRUE(trans.StartPlayout(id_2));
    EXPECT_TRUE(trans.StartPlayout(id_3));

    webrtc::SleepMs(kPacketDurationMs * kPackets);

    webrtc::CallStatistics stats_0;
    webrtc::CallStatistics stats_1;
    webrtc::CallStatistics stats_2;
    webrtc::CallStatistics stats_3;
    EXPECT_TRUE(trans.GetReceiverStatistics(id_0, &stats_0));
    EXPECT_TRUE(trans.GetReceiverStatistics(id_1, &stats_1));
    EXPECT_TRUE(trans.GetReceiverStatistics(id_2, &stats_2));
    EXPECT_TRUE(trans.GetReceiverStatistics(id_3, &stats_3));

    // We expect stream 0 to be filtered out totally, but since it may join the
    // call earlier than other streams and the beginning packets might have got
    // through. So we only expect |packetsReceived| to be close to zero.
    EXPECT_NEAR(stats_0.packetsReceived, 0, 2);
    // We expect |packetsReceived| to match |kPackets|, but the actual value
    // depends on the sleep timer. So we allow a small off from |kPackets|.
    EXPECT_NEAR(stats_1.packetsReceived, kPackets, 2);
    EXPECT_NEAR(stats_2.packetsReceived, kPackets, 2);
    EXPECT_NEAR(stats_3.packetsReceived, kPackets, 2);
  }

  remove(silence_file.c_str());
}

}  // namespace voetest
