// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/microphone.h"
#include "starboard/nplb/microphone_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

#if SB_API_VERSION >= SB_MICROPHONE_REQUIRED_VERSION || SB_HAS(MICROPHONE)

TEST(SbMicrophoneGetAvailableTest, SunnyDay) {
  SbMicrophoneInfo info_array[kMaxNumberOfMicrophone];
  int available_microphones =
      SbMicrophoneGetAvailable(info_array, kMaxNumberOfMicrophone);
  EXPECT_GE(available_microphones, 0);
}

TEST(SbMicrophoneGetAvailableTest, RainyDay0NumberOfMicrophone) {
  SbMicrophoneInfo info_array[kMaxNumberOfMicrophone];
  if (SbMicrophoneGetAvailable(info_array, kMaxNumberOfMicrophone) > 0) {
    int available_microphones = SbMicrophoneGetAvailable(info_array, 0);
    EXPECT_GT(available_microphones, 0);
  }
}

TEST(SbMicrophoneGetAvailableTest, RainyDayNegativeNumberOfMicrophone) {
  SbMicrophoneInfo info_array[kMaxNumberOfMicrophone];
  if (SbMicrophoneGetAvailable(info_array, kMaxNumberOfMicrophone) > 0) {
    int available_microphones = SbMicrophoneGetAvailable(info_array, -10);
    EXPECT_GT(available_microphones, 0);
  }
}

TEST(SbMicrophoneGetAvailableTest, RainyDayNULLInfoArray) {
  SbMicrophoneInfo info_array[kMaxNumberOfMicrophone];
  if (SbMicrophoneGetAvailable(info_array, kMaxNumberOfMicrophone) > 0) {
    int available_microphones =
        SbMicrophoneGetAvailable(NULL, kMaxNumberOfMicrophone);
    EXPECT_GT(available_microphones, 0);
  }
}

#if SB_API_VERSION >= 9

template<std::size_t N>
bool IsNullTerminated(const char(&str)[N]) {
  for (size_t i = 0; i < N; ++i) {
    if (str[i] == '\0') {
      return true;
    }
  }
  return false;
}

TEST(SbMicrophoneGetAvailableTest, LabelIsNullTerminated) {
  const int kInfoSize = 10;
  SbMicrophoneInfo infos[kInfoSize];
  int count = SbMicrophoneGetAvailable(infos, kInfoSize);
  for (int i = 0; i < std::min(count, kInfoSize); ++i) {
    EXPECT_TRUE(IsNullTerminated(infos[i].label));
  }
}

TEST(SbMicrophoneGetAvailableTest, LabelIsValid) {
  const char* kPoisonLabel = "BadLabel";
  SbMicrophoneInfo info;
  SbStringCopy(info.label, kPoisonLabel, SB_ARRAY_SIZE(info.label));

  if (SbMicrophoneGetAvailable(&info, 1) > 0) {
    ASSERT_TRUE(IsNullTerminated(info.label));
    size_t count = static_cast<size_t>(SbStringGetLength(kPoisonLabel));
    EXPECT_NE(0, SbStringCompare(info.label, kPoisonLabel, count));
  }
}

#endif  //  SB_API_VERSION >= 9

#endif  // SB_API_VERSION >= SB_MICROPHONE_REQUIRED_VERSION ||
        // SB_HAS(MICROPHONE)

}  // namespace
}  // namespace nplb
}  // namespace starboard
