/*
 *  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.
 */

#include "webrtc/voice_engine/include/voe_codec.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_device/include/fake_audio_device.h"
#include "webrtc/test/testsupport/gtest_disable.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/voice_engine_defines.h"

namespace webrtc {
namespace voe {
namespace {

class VoECodecTest : public ::testing::Test {
 protected:
  VoECodecTest()
      : voe_(VoiceEngine::Create()),
        base_(VoEBase::GetInterface(voe_)),
        voe_codec_(VoECodec::GetInterface(voe_)),
        channel_(-1),
        adm_(new FakeAudioDeviceModule),
        red_payload_type_(-1) {
  }

  ~VoECodecTest() {}

  void TearDown() {
    base_->DeleteChannel(channel_);
    base_->Terminate();
    base_->Release();
    voe_codec_->Release();
    VoiceEngine::Delete(voe_);
  }

  void SetUp() {
    // Check if all components are valid.
    ASSERT_TRUE(voe_ != NULL);
    ASSERT_TRUE(base_ != NULL);
    ASSERT_TRUE(voe_codec_ != NULL);
    ASSERT_TRUE(adm_.get() != NULL);
    ASSERT_EQ(0, base_->Init(adm_.get()));
    channel_ = base_->CreateChannel();
    ASSERT_NE(-1, channel_);

    CodecInst my_codec;

    bool primary_found = false;
    bool valid_secondary_found = false;
    bool invalid_secondary_found = false;

    // Find primary and secondary codecs.
    int num_codecs = voe_codec_->NumOfCodecs();
    int n = 0;
    while (n < num_codecs && (!primary_found || !valid_secondary_found ||
        !invalid_secondary_found || red_payload_type_ < 0)) {
      EXPECT_EQ(0, voe_codec_->GetCodec(n, my_codec));
      if (!STR_CASE_CMP(my_codec.plname, "isac") && my_codec.plfreq == 16000) {
        memcpy(&valid_secondary_, &my_codec, sizeof(my_codec));
        valid_secondary_found = true;
      } else if (!STR_CASE_CMP(my_codec.plname, "isac") &&
          my_codec.plfreq == 32000) {
        memcpy(&invalid_secondary_, &my_codec, sizeof(my_codec));
        invalid_secondary_found = true;
      } else if (!STR_CASE_CMP(my_codec.plname, "L16") &&
          my_codec.plfreq == 16000) {
        memcpy(&primary_, &my_codec, sizeof(my_codec));
        primary_found = true;
      } else if (!STR_CASE_CMP(my_codec.plname, "RED")) {
        red_payload_type_ = my_codec.pltype;
      }
      n++;
    }

    EXPECT_TRUE(primary_found);
    EXPECT_TRUE(valid_secondary_found);
    EXPECT_TRUE(invalid_secondary_found);
    EXPECT_NE(-1, red_payload_type_);
  }

  VoiceEngine* voe_;
  VoEBase* base_;
  VoECodec* voe_codec_;
  int channel_;
  CodecInst primary_;
  CodecInst valid_secondary_;
  rtc::scoped_ptr<FakeAudioDeviceModule> adm_;

  // A codec which is not valid to be registered as secondary codec.
  CodecInst invalid_secondary_;
  int red_payload_type_;
};

TEST(VoECodecInst, TestCompareCodecInstances) {
  CodecInst codec1, codec2;
  memset(&codec1, 0, sizeof(CodecInst));
  memset(&codec2, 0, sizeof(CodecInst));

  codec1.pltype = 101;
  strncpy(codec1.plname, "isac", 4);
  codec1.plfreq = 8000;
  codec1.pacsize = 110;
  codec1.channels = 1;
  codec1.rate = 8000;
  memcpy(&codec2, &codec1, sizeof(CodecInst));
  // Compare two codecs now.
  EXPECT_TRUE(codec1 == codec2);
  EXPECT_FALSE(codec1 != codec2);

  // Changing pltype.
  codec2.pltype = 102;
  EXPECT_FALSE(codec1 == codec2);
  EXPECT_TRUE(codec1 != codec2);

  // Reset to codec2 to codec1 state.
  memcpy(&codec2, &codec1, sizeof(CodecInst));
  // payload name should be case insensitive.
  strncpy(codec2.plname, "ISAC", 4);
  EXPECT_TRUE(codec1 == codec2);

  // Test modifying the |plfreq|
  codec2.plfreq = 16000;
  EXPECT_FALSE(codec1 == codec2);

  // Reset to codec2 to codec1 state.
  memcpy(&codec2, &codec1, sizeof(CodecInst));
  // Test modifying the |pacsize|.
  codec2.pacsize = 440;
  EXPECT_FALSE(codec1 == codec2);

  // Reset to codec2 to codec1 state.
  memcpy(&codec2, &codec1, sizeof(CodecInst));
  // Test modifying the |channels|.
  codec2.channels = 2;
  EXPECT_FALSE(codec1 == codec2);

  // Reset to codec2 to codec1 state.
  memcpy(&codec2, &codec1, sizeof(CodecInst));
  // Test modifying the |rate|.
  codec2.rate = 0;
  EXPECT_FALSE(codec1 == codec2);
}

}  // namespace
}  // namespace voe
}  // namespace webrtc
