// Copyright 2015 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 <string.h>

#include "starboard/common/string.h"
#include "starboard/memory.h"
#include "starboard/system.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

// Size of appropriate value buffer.
const size_t kValueSize = 1024;

bool IsCEDevice(SbSystemDeviceType device_type) {
  switch (device_type) {
    case kSbSystemDeviceTypeBlueRayDiskPlayer:
    case kSbSystemDeviceTypeGameConsole:
    case kSbSystemDeviceTypeOverTheTopBox:
    case kSbSystemDeviceTypeSetTopBox:
    case kSbSystemDeviceTypeTV:
      return true;
    case kSbSystemDeviceTypeDesktopPC:
    case kSbSystemDeviceTypeUnknown:
    default:
      return false;
  }
}

void BasicTest(SbSystemPropertyId id,
               bool expect_result,
               bool expected_result,
               int line) {
#define LOCAL_CONTEXT "Context : id=" << id << ", line=" << line;
  char value[kValueSize] = {0};
  SbMemorySet(value, 0xCD, kValueSize);
  bool result = SbSystemGetProperty(id, value, kValueSize);
  if (expect_result) {
    EXPECT_EQ(expected_result, result) << LOCAL_CONTEXT;
  }
  if (result) {
    EXPECT_NE('\xCD', value[0]) << LOCAL_CONTEXT;
    int len = static_cast<int>(SbStringGetLength(value));
    EXPECT_GT(len, 0) << LOCAL_CONTEXT;
  } else {
    EXPECT_EQ('\xCD', value[0]) << LOCAL_CONTEXT;
  }
#undef LOCAL_CONTEXT
}

void UnmodifiedOnFailureTest(SbSystemPropertyId id, int line) {
  char value[kValueSize] = {0};
  SbMemorySet(value, 0xCD, kValueSize);
  for (size_t i = 0; i <= kValueSize; ++i) {
    if (SbSystemGetProperty(id, value, i)) {
      return;
    }
    for (auto ch : value) {
      ASSERT_EQ('\xCD', ch) << "Context : id=" << id << ", line=" << line;
    }
  }
}

TEST(SbSystemGetPropertyTest, ReturnsRequired) {
  BasicTest(kSbSystemPropertyFriendlyName, true, true, __LINE__);
  BasicTest(kSbSystemPropertyPlatformName, true, true, __LINE__);

  BasicTest(kSbSystemPropertyChipsetModelNumber, false, true, __LINE__);
  BasicTest(kSbSystemPropertyFirmwareVersion, false, true, __LINE__);
#if SB_API_VERSION >= 11
  BasicTest(kSbSystemPropertyOriginalDesignManufacturerName,
            false, true, __LINE__);
#else
  BasicTest(kSbSystemPropertyNetworkOperatorName, false, true, __LINE__);
#endif
  BasicTest(kSbSystemPropertySpeechApiKey, false, true, __LINE__);

  if (IsCEDevice(SbSystemGetDeviceType())) {
    BasicTest(kSbSystemPropertyBrandName, true, true, __LINE__);
    BasicTest(kSbSystemPropertyModelName, true, true, __LINE__);
    BasicTest(kSbSystemPropertyModelYear, false, true, __LINE__);
  } else {
    BasicTest(kSbSystemPropertyBrandName, false, true, __LINE__);
    BasicTest(kSbSystemPropertyModelName, false, true, __LINE__);
    BasicTest(kSbSystemPropertyModelYear, false, true, __LINE__);
  }
}

TEST(SbSystemGetPropertyTest, FailsGracefullyZeroBufferLength) {
  char value[kValueSize] = {0};
  EXPECT_FALSE(SbSystemGetProperty(kSbSystemPropertyFriendlyName, value, 0));
}

TEST(SbSystemGetPropertyTest, FailsGracefullyNullBuffer) {
  EXPECT_FALSE(
      SbSystemGetProperty(kSbSystemPropertyFriendlyName, NULL, kValueSize));
}

TEST(SbSystemGetPropertyTest, FailsGracefullyNullBufferAndZeroLength) {
  EXPECT_FALSE(SbSystemGetProperty(kSbSystemPropertyFriendlyName, NULL, 0));
}

TEST(SbSystemGetPropertyTest, FailsGracefullyBogusId) {
  BasicTest(static_cast<SbSystemPropertyId>(99999), true, false, __LINE__);
}

TEST(SbSystemGetPropertyTest, DoesNotTouchOutputBufferOnFailureForDefinedIds) {
  UnmodifiedOnFailureTest(kSbSystemPropertyChipsetModelNumber, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyFirmwareVersion, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyFriendlyName, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyManufacturerName, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyBrandName, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyModelName, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertyModelYear, __LINE__);
#if SB_API_VERSION >= 11
  UnmodifiedOnFailureTest(kSbSystemPropertyOriginalDesignManufacturerName,
                          __LINE__);
#else
  UnmodifiedOnFailureTest(kSbSystemPropertyNetworkOperatorName, __LINE__);
#endif
  UnmodifiedOnFailureTest(kSbSystemPropertyPlatformName, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPropertySpeechApiKey, __LINE__);
#if SB_API_VERSION >= 5
  UnmodifiedOnFailureTest(kSbSystemPropertyUserAgentAuxField, __LINE__);
#endif  // SB_API_VERSION >= 5
}

TEST(SbSystemGetPropertyTest, SpeechApiKeyNotLeaked) {
  static const size_t kSize = 512;
  char speech_api_key[kSize] = {0};
  bool has_speech_key =
      SbSystemGetProperty(kSbSystemPropertySpeechApiKey, speech_api_key, kSize);

  if (!has_speech_key) {
    EXPECT_EQ(0, SbStringGetLength(speech_api_key));
    return;
  }

  SbSystemPropertyId enum_values[] = {
    kSbSystemPropertyChipsetModelNumber,
    kSbSystemPropertyFirmwareVersion,
    kSbSystemPropertyFriendlyName,
    kSbSystemPropertyManufacturerName,
    kSbSystemPropertyModelName,
    kSbSystemPropertyModelYear,
#if SB_API_VERSION >= 11
    kSbSystemPropertyOriginalDesignManufacturerName,
#else
    kSbSystemPropertyNetworkOperatorName,
#endif
    kSbSystemPropertyPlatformName,
  };

  for (SbSystemPropertyId val : enum_values) {
    char value[kSize] = {0};

    if (SbSystemGetProperty(val, value, kSize)) {
      ASSERT_FALSE(SbStringFindString(value, speech_api_key));
    }
  }
}

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