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

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

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/audio_device/include/fake_audio_device.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_;
  std::unique_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
