// Copyright 2017 Google Inc. 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/system.h"

#include <string>

#include "starboard/log.h"
#include "starboard/shared/uwp/application_uwp.h"
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/string.h"

using Windows::Security::ExchangeActiveSyncProvisioning::
    EasClientDeviceInformation;
using Windows::System::Profile::AnalyticsInfo;
using Windows::System::Profile::AnalyticsVersionInfo;

namespace sbwin32 = starboard::shared::win32;

namespace {
bool CopyStringAndTestIfSuccess(char* out_value,
                                int value_length,
                                const char* from_value) {
  if (SbStringGetLength(from_value) + 1 > value_length)
    return false;
  SbStringCopy(out_value, from_value, value_length);
  return true;
}

const std::size_t kOsVersionSize = 128;

struct WindowsVersion {
  uint16_t major_version;
  uint16_t minor_version;
  uint16_t build_version;
  uint16_t revision;
};

bool GetWindowsVersion(WindowsVersion* version) {
  SB_DCHECK(version);
  AnalyticsVersionInfo^ version_info = AnalyticsInfo::VersionInfo;
  std::string device_family_version =
      starboard::shared::win32::platformStringToString(
          version_info->DeviceFamilyVersion);
  if (device_family_version.empty()) {
    return false;
  }
  uint64_t version_info_all =
      SbStringParseUInt64(device_family_version.c_str(), nullptr, 10);
  if (version_info_all == 0) {
    return false;
  }
  version->major_version = (version_info_all >> 48) & 0xFFFF;
  version->minor_version = (version_info_all >> 32) & 0xFFFF;
  version->build_version = (version_info_all >> 16) & 0xFFFF;
  version->revision = version_info_all & 0xFFFF;
  return true;
}

}  // namespace

bool SbSystemGetProperty(SbSystemPropertyId property_id,
                         char* out_value,
                         int value_length) {
  if (!out_value || !value_length) {
    return false;
  }

  using sbwin32::platformStringToString;

  switch (property_id) {
    case kSbSystemPropertyChipsetModelNumber:
    case kSbSystemPropertyModelYear:
    case kSbSystemPropertyNetworkOperatorName:
    case kSbSystemPropertySpeechApiKey:
    case kSbSystemPropertyUserAgentAuxField:
      return false;
    case kSbSystemPropertyBrandName: {
      EasClientDeviceInformation^ current_device_info =
          ref new EasClientDeviceInformation();
      std::string brand_name =
          platformStringToString(current_device_info->SystemManufacturer);
      if (brand_name.empty()) {
        return false;
      }
      return CopyStringAndTestIfSuccess(out_value, value_length,
                                        brand_name.c_str());
    }
    case kSbSystemPropertyFirmwareVersion: {
      WindowsVersion version = {0};
      if (!GetWindowsVersion(&version)) {
        return false;
      }
      int return_value = SbStringFormatF(
          out_value, value_length, "%u.%u.%u.%u", version.major_version,
          version.minor_version, version.build_version, version.revision);
      return ((return_value > 0) && (return_value < value_length));
    }
    case kSbSystemPropertyModelName: {
      EasClientDeviceInformation^ current_device_info =
          ref new EasClientDeviceInformation();
      std::string sku =
        platformStringToString(current_device_info->SystemSku);

      std::string friendly_name;

      // TODO: Move this logic into xb1 specific directory.
      if (sku == "XBOX_ONE_DU") {
        friendly_name = "XboxOne";
      } else if (sku == "XBOX_ONE_ED") {
        friendly_name = "XboxOne S";
      } else if (sku == "XBOX_ONE_CH" || sku == "XBOX_ONE_SC") {
        friendly_name = "XboxOne X";
      } else {
        friendly_name = "XboxOne " + sku;
      }

      return CopyStringAndTestIfSuccess(out_value, value_length,
                                        friendly_name.c_str());
    }
    case kSbSystemPropertyFriendlyName: {
      EasClientDeviceInformation^ current_device_info =
          ref new EasClientDeviceInformation();
      std::string friendly_name =
          platformStringToString(current_device_info->FriendlyName);
      if (friendly_name.empty()) {
        return false;
      }
      return CopyStringAndTestIfSuccess(out_value, value_length,
                                        friendly_name.c_str());
    }
    case kSbSystemPropertyPlatformName: {
      EasClientDeviceInformation^ current_device_info =
          ref new EasClientDeviceInformation();
      std::string operating_system =
          platformStringToString(current_device_info->OperatingSystem);

      AnalyticsVersionInfo^ version_info = AnalyticsInfo::VersionInfo;
      std::string os_name_and_version =
          starboard::shared::win32::platformStringToString(
              current_device_info->OperatingSystem);
      if (os_name_and_version.empty()) {
        return false;
      }

      WindowsVersion os_version;
      if (!GetWindowsVersion(&os_version)) {
        return false;
      }

      os_name_and_version += " ";
      char os_version_buffer[kOsVersionSize];
      os_version_buffer[0] = '\0';

      int return_value =
          SbStringFormatF(os_version_buffer, value_length, "%u.%u",
                          os_version.major_version, os_version.minor_version);
      if ((return_value < 0) || (return_value >= value_length)) {
        return false;
      }

      os_name_and_version.append(os_version_buffer);

      return CopyStringAndTestIfSuccess(out_value, value_length,
                                        os_name_and_version.c_str());
    }
    case kSbSystemPropertyPlatformUuid: {
      SB_NOTIMPLEMENTED();
      return CopyStringAndTestIfSuccess(out_value, value_length, "N/A");
    }
    default:
      SB_DLOG(WARNING) << __FUNCTION__
                       << ": Unrecognized property: " << property_id;
      break;
  }
  return false;
}
