// Copyright 2017 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/shared/uwp/application_uwp.h"

#include <D3D11.h>
#include <D3D11_1.h>
#include <WinSock2.h>
#include <collection.h>
#include <mfapi.h>
#include <ppltasks.h>
#include <windows.graphics.display.core.h>
#include <windows.h>
#include <windows.system.display.h>

#include <cstdlib>
#include <memory>
#include <string>
#include <vector>

#include "starboard/common/device_type.h"
#include "starboard/common/file.h"
#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/common/queue.h"
#include "starboard/common/semaphore.h"
#include "starboard/common/string.h"
#include "starboard/common/system_property.h"
#include "starboard/common/thread.h"
#include "starboard/configuration_constants.h"
#include "starboard/event.h"
#include "starboard/input.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
#include "starboard/shared/starboard/media/key_system_supportability_cache.h"
#include "starboard/shared/starboard/media/mime_supportability_cache.h"
#include "starboard/shared/starboard/net_args.h"
#include "starboard/shared/starboard/net_log.h"
#include "starboard/shared/uwp/analog_thumbstick_input_thread.h"
#include "starboard/shared/uwp/app_accessors.h"
#include "starboard/shared/uwp/async_utils.h"
#include "starboard/shared/uwp/extended_resources_manager.h"
#include "starboard/shared/uwp/log_file_impl.h"
#include "starboard/shared/uwp/watchdog_log.h"
#include "starboard/shared/uwp/window_internal.h"
#include "starboard/shared/win32/thread_private.h"
#include "starboard/shared/win32/video_decoder.h"
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/system.h"

namespace starboard {

using Microsoft::WRL::ComPtr;
using shared::starboard::Application;
using shared::starboard::CommandLine;
using shared::starboard::kNetArgsCommandSwitchWait;
using shared::starboard::kNetLogCommandSwitchWait;
using shared::starboard::NetArgsWaitForPayload;
using shared::starboard::NetLogFlushThenClose;
using shared::starboard::NetLogWaitForClientConnected;
using shared::uwp::ApplicationUwp;
using shared::uwp::RunInMainThreadAsync;
using shared::uwp::WaitForResult;
using shared::win32::platformStringToString;
using shared::win32::stringToPlatformString;
using shared::win32::wchar_tToUTF8;
using ::starboard::shared::starboard::media::KeySystemSupportabilityCache;
using ::starboard::shared::starboard::media::MimeSupportabilityCache;
using Windows::ApplicationModel::SuspendingDeferral;
using Windows::ApplicationModel::SuspendingEventArgs;
using Windows::ApplicationModel::Activation::ActivationKind;
using Windows::ApplicationModel::Activation::DialReceiverActivatedEventArgs;
using Windows::ApplicationModel::Activation::IActivatedEventArgs;
using Windows::ApplicationModel::Activation::IProtocolActivatedEventArgs;
using Windows::ApplicationModel::Core::CoreApplication;
using Windows::ApplicationModel::Core::CoreApplicationView;
using Windows::ApplicationModel::Core::IFrameworkView;
using Windows::ApplicationModel::Core::IFrameworkViewSource;
using Windows::ApplicationModel::ExtendedExecution::ExtendedExecutionReason;
using Windows::ApplicationModel::ExtendedExecution::ExtendedExecutionResult;
using Windows::ApplicationModel::ExtendedExecution::
    ExtendedExecutionRevokedEventArgs;
using Windows::ApplicationModel::ExtendedExecution::ExtendedExecutionSession;
using Windows::Devices::Enumeration::DeviceInformation;
using Windows::Devices::Enumeration::DeviceInformationUpdate;
using Windows::Devices::Enumeration::DeviceWatcher;
using Windows::Devices::Enumeration::DeviceWatcherStatus;
using Windows::Foundation::EventHandler;
using Windows::Foundation::IAsyncOperation;
using Windows::Foundation::TimeSpan;
using Windows::Foundation::TypedEventHandler;
using Windows::Foundation::Uri;
using Windows::Foundation::Collections::IVectorView;
using Windows::Foundation::Metadata::ApiInformation;
using Windows::Globalization::Calendar;
using Windows::Graphics::Display::AdvancedColorInfo;
using Windows::Graphics::Display::AdvancedColorKind;
using Windows::Graphics::Display::DisplayInformation;
using Windows::Graphics::Display::HdrMetadataFormat;
using Windows::Graphics::Display::Core::HdmiDisplayColorSpace;
using Windows::Graphics::Display::Core::HdmiDisplayHdr2086Metadata;
using Windows::Graphics::Display::Core::HdmiDisplayHdrOption;
using Windows::Graphics::Display::Core::HdmiDisplayInformation;
using Windows::Graphics::Display::Core::HdmiDisplayMode;
using Windows::Media::Protection::HdcpProtection;
using Windows::Media::Protection::HdcpSession;
using Windows::Media::Protection::HdcpSetProtectionResult;
using Windows::Security::Authentication::Web::Core::WebTokenRequestResult;
using Windows::Security::Authentication::Web::Core::WebTokenRequestStatus;
using Windows::Security::Credentials::WebAccountProvider;
using Windows::Storage::FileAttributes;
using Windows::Storage::KnownFolders;
using Windows::Storage::StorageFile;
using Windows::Storage::StorageFolder;
using Windows::System::UserAuthenticationStatus;
using Windows::System::Threading::ThreadPoolTimer;
using Windows::System::Threading::TimerElapsedHandler;
using Windows::UI::Core::CoreDispatcherPriority;
using Windows::UI::Core::CoreProcessEventsOption;
using Windows::UI::Core::CoreWindow;
using Windows::UI::Core::DispatchedHandler;
using Windows::UI::Core::KeyEventArgs;
using Windows::UI::ViewManagement::ApplicationView;
using Windows::UI::ViewManagement::ApplicationViewScaling;

namespace {

const Platform::String ^ kGenericPnpMonitorAqs = ref new Platform::String(
    L"System.Devices.InterfaceClassGuid:=\"{e6f07b5f-ee97-4a90-b076-"
    L"33f57bf4eaa7}\" AND "
    L"System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#"
    L"True");

const uint32_t kYuv420BitsPerPixelForHdr10Mode = 24;

// The number of seconds to wait after requesting application stop. This is used
// to exit the app when a suspend has been requested. This is a temporary
// behavior that should be removed when not needed anymore.
const SbTime kAppExitWaitTime = kSbTimeSecond * 30;

// Per Microsoft, HdcpProtection::On means HDCP 1.x required.
const HdcpProtection kHDCPProtectionMode = HdcpProtection::On;

const int kWinSockVersionMajor = 2;
const int kWinSockVersionMinor = 2;

const char kDialParamPrefix[] = "cobalt-dial:?";
const char kLogPathSwitch[] = "xb1_log_file";
// A special log that the app will periodically write to. This allows
// tests to determine if the app is still alive.
const char kWatchDogLog[] = "xb1_watchdog_log";
const char kStarboardArgumentsPath[] = "arguments\\starboard_arguments.txt";
const int64_t kMaxArgumentFileSizeBytes = 4 * 1024 * 1024;

int main_return_value = 0;

// IDisplayRequest is both "non-agile" and apparently
// incompatible with Platform::Agile (it doesn't fully implement
// a thread marshaller). We must neither use ComPtr or Platform::Agile
// here. We manually create, access release on the main app thread only.
ABI::Windows::System::Display::IDisplayRequest* display_request = nullptr;

// If an argv[0] is required, fill it in with the result of
// GetModuleFileName()
std::string GetArgvZero() {
  const size_t kMaxModuleNameSize = kSbFileMaxName;
  std::vector<wchar_t> buffer(kMaxModuleNameSize);
  DWORD result = GetModuleFileName(NULL, buffer.data(), buffer.size());
  std::string arg;
  if (result == 0) {
    arg = "unknown";
  } else {
    arg = wchar_tToUTF8(buffer.data(), result).c_str();
  }
  return arg;
}

int MakeDeviceId() {
  // TODO: Devices MIGHT have colliding hashcodes. Some other unique int
  // ID generation tool would be better.
  using Windows::Security::ExchangeActiveSyncProvisioning::
      EasClientDeviceInformation;
  auto device_information = ref new EasClientDeviceInformation();
  Platform::String ^ device_id_string = device_information->Id.ToString();
  return device_id_string->GetHashCode();
}

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)

void SplitArgumentsIntoVector(std::string* args,
                              std::vector<std::string>* result) {
  SB_DCHECK(args);
  SB_DCHECK(result);
  while (!args->empty()) {
    size_t next = args->find(';');
    result->push_back(args->substr(0, next));
    if (next == std::string::npos) {
      return;
    }
    *args = args->substr(next + 1);
  }
}

// Parses a starboard: URI scheme by splitting args at ';' boundaries.
std::vector<std::string> ParseStarboardUri(const std::string& uri) {
  std::vector<std::string> result;
  result.push_back(GetArgvZero());

  size_t index = uri.find(':');
  if (index == std::string::npos) {
    return result;
  }

  std::string args = uri.substr(index + 1);
  SplitArgumentsIntoVector(&args, &result);

  return result;
}

void AddArgumentsFromFile(const char* path, std::vector<std::string>* args) {
  ScopedFile file(path, kSbFileOpenOnly | kSbFileRead);
  if (!file.IsValid()) {
    SB_LOG(INFO) << path << " is not valid for arguments.";
    return;
  }

  int64_t file_size = file.GetSize();
  if (file_size > kMaxArgumentFileSizeBytes) {
    SB_DLOG(ERROR) << "The arguments file is too big.";
    return;
  }

  if (file_size <= 0) {
    SB_DLOG(INFO) << "Arguments file is empty.";
    return;
  }

  std::string argument_string(file_size, '\0');
  int return_value = file.ReadAll(&argument_string[0], file_size);
  if (return_value < 0) {
    SB_DLOG(ERROR) << "Error while reading arguments from file.";
    return;
  }
  argument_string.resize(return_value);

  SplitArgumentsIntoVector(&argument_string, args);
}

void TryAddCommandArgsFromStarboardFile(std::vector<std::string>* args) {
  std::vector<char> content_directory(kSbFileMaxName);
  content_directory[0] = '\0';

  if (!SbSystemGetPath(kSbSystemPathContentDirectory, content_directory.data(),
                       content_directory.size())) {
    return;
  }

  std::string arguments_file_path(static_cast<char*>(content_directory.data()));
  arguments_file_path += kSbFileSepString;
  arguments_file_path += kStarboardArgumentsPath;

  AddArgumentsFromFile(arguments_file_path.c_str(), args);
}

void AddCommandArgsFromNetArgs(SbTime timeout, std::vector<std::string>* args) {
  // Detect if NetArgs is enabled for this run. If so then receive and
  // then merge the arguments into this run.
  SB_LOG(INFO) << "Waiting for net args...";
  std::vector<std::string> net_args = NetArgsWaitForPayload(timeout);
  if (!net_args.empty()) {
    std::stringstream ss;
    ss << "Found Net Args:\n";
    for (const std::string& s : net_args) {
      ss << "  " << s << "\n";
    }
    SB_LOG(INFO) << ss.str();
  }
  // Merge command arguments.
  args->insert(args->end(), net_args.begin(), net_args.end());
}

#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)

std::unique_ptr<Application::Event> MakeDeepLinkEvent(
    const std::string& uri_string) {
  SB_LOG(INFO) << "Navigate to: [" << uri_string << "]";
  const size_t kMaxDeepLinkSize = 128 * 1024;
  const std::size_t uri_size = uri_string.size();
  if (uri_size > kMaxDeepLinkSize) {
    SB_NOTREACHED() << "App launch data too big: " << uri_size;
    return nullptr;
  }

  const int kBufferSize = static_cast<int>(uri_string.size()) + 1;
  char* deep_link = new char[kBufferSize];
  SB_DCHECK(deep_link);
  starboard::strlcpy(deep_link, uri_string.c_str(), kBufferSize);

  return std::unique_ptr<Application::Event>(
      new Application::Event(kSbEventTypeLink, deep_link,
                             Application::DeleteArrayDestructor<const char*>));
}

// Returns if |full_string| ends with |substring|.
bool ends_with(const std::string& full_string, const std::string& substring) {
  if (substring.length() > full_string.length()) {
    return false;
  }
  return std::equal(substring.rbegin(), substring.rend(), full_string.rbegin());
}

std::string GetBinaryName() {
  std::string full_binary_path = GetArgvZero();
  std::string::size_type index = full_binary_path.rfind(kSbFileSepChar);
  if (index == std::string::npos) {
    return full_binary_path;
  }

  return full_binary_path.substr(index + 1);
}

void OnDeviceAdded(DeviceWatcher ^, DeviceInformation ^) {
  SB_LOG(INFO) << "DisplayStatusWatcher::OnDeviceAdded";
  // We need delay to give time for the display initializing after connect.
  SbThreadSleep(15 * kSbTimeMillisecond);

  MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();

  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeUnfreeze, NULL, NULL));
  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeReveal, NULL, NULL));
  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeFocus, NULL, NULL));
}

void OnDeviceRemoved(DeviceWatcher ^, DeviceInformationUpdate ^) {
  // Without signing on OnDeviceRemoved, callback OnDeviceAdded doesn't work.
  SB_LOG(INFO) << "DisplayStatusWatcher::OnDeviceRemoved";

  MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();

  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeBlur, NULL, NULL));
  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeConceal, NULL, NULL));
  ApplicationUwp::Get()->Inject(
      new ApplicationUwp::Event(kSbEventTypeFreeze, NULL, NULL));
}

}  // namespace

namespace shared {
namespace win32 {
// Called into drm_system_playready.cc
extern void DrmSystemOnUwpResume();
}  // namespace win32
}  // namespace shared

ref class App sealed : public IFrameworkView {
 public:
  App(SbTimeMonotonic start_time)
      : application_start_time_{start_time},
        previously_activated_(false),
#if SB_API_VERSION >= 15
        application_(SbEventHandle),
#endif  // SB_API_VERSION >= 15
        is_online_(true) {
  }

  // IFrameworkView methods.
  virtual void Initialize(CoreApplicationView ^ application_view) {
    // The following incantation creates a DisplayRequest and obtains
    // its underlying COM interface.
    ComPtr<IInspectable> inspectable = reinterpret_cast<IInspectable*>(
        ref new Windows::System::Display::DisplayRequest());
    ComPtr<ABI::Windows::System::Display::IDisplayRequest> dr;
    inspectable.As(&dr);
    display_request = dr.Detach();

    SbAudioSinkPrivate::Initialize();
    Windows::Networking::Connectivity::NetworkInformation::
        NetworkStatusChanged += ref new Windows::Networking::Connectivity::
            NetworkStatusChangedEventHandler(this,
                                             &App::OnNetworkStatusChanged);
    CoreApplication::Suspending +=
        ref new EventHandler<SuspendingEventArgs ^>(this, &App::OnSuspending);
    CoreApplication::Resuming +=
        ref new EventHandler<Object ^>(this, &App::OnResuming);
    application_view->Activated +=
        ref new TypedEventHandler<CoreApplicationView ^, IActivatedEventArgs ^>(
            this, &App::OnActivated);

    MimeSupportabilityCache::GetInstance()->SetCacheEnabled(true);
    KeySystemSupportabilityCache::GetInstance()->SetCacheEnabled(true);
  }

  virtual void SetWindow(CoreWindow ^ window) {
    ApplicationUwp::Get()->SetCoreWindow(window);
    window->KeyUp += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(
        this, &App::OnKeyUp);
    window->KeyDown += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(
        this, &App::OnKeyDown);
  }

  virtual void Load(Platform::String ^ entry_point) {
    entry_point_ = wchar_tToUTF8(entry_point->Data());
  }

  virtual void Run() {
#if SB_API_VERSION >= 15
    main_return_value =
        SbRunStarboardMain(static_cast<int>(argv_.size()),
                           const_cast<char**>(argv_.data()), SbEventHandle);
#else
    main_return_value = application_.Run(static_cast<int>(argv_.size()),
                                         const_cast<char**>(argv_.data()));
#endif  // SB_API_VERSION >= 15
  }
  virtual void Uninitialize() {
    SbAudioSinkPrivate::TearDown();
    display_request->Release();
    display_request = nullptr;
  }

  void CompleteSuspendDeferral() {
    if (suspend_deferral_ != nullptr) {
      // Completing the deferral results in the app being suspended by the OS.
      SB_LOG(INFO) << "App is ready to be suspended.";
      suspend_deferral_->Complete();
      suspend_deferral_ = nullptr;
    }
  }

  void ExtendedExecutionSessionRevoked(Object ^ sender,
                                       ExtendedExecutionRevokedEventArgs ^
                                           args) {
    CompleteSuspendDeferral();
  }

  void ForceQuit() {
    SB_LOG(ERROR) << "Application is not safe to suspend, forcing exit.";
    ApplicationUwp::Get()->DispatchAndDelete(
        new ApplicationUwp::Event(kSbEventTypeStop, NULL, NULL));
    auto extended_resources_manager =
        shared::uwp::ExtendedResourcesManager::GetInstance();
    if (extended_resources_manager) {
      extended_resources_manager->Quit();
    }
  }

  void OnNetworkStatusChanged(Object ^ sender) {
    auto connection_profile = Windows::Networking::Connectivity::
        NetworkInformation::GetInternetConnectionProfile();
    bool is_online =
        connection_profile &&
        connection_profile->GetNetworkConnectivityLevel() !=
            Windows::Networking::Connectivity::NetworkConnectivityLevel::None;

    // Only inject event if the online status changed.
    if (is_online != is_online_) {
      auto* application = starboard::shared::starboard::Application::Get();

      // Verify we have an application and dispatcher before injecting events.
      if (application == nullptr) {
        SB_LOG(ERROR) << "OnNetworkStatusChanged has no application.";
        SB_DCHECK(false);
        return;
      }
      if (starboard::shared::uwp::GetDispatcher().Get() == nullptr) {
        SB_LOG(ERROR) << "OnNetworkStatusChanged has no dispatcher.";
        SB_DCHECK(false);
        return;
      }

      if (is_online) {
        application->InjectOsNetworkConnectedEvent();
      } else {
        application->InjectOsNetworkDisconnectedEvent();
      }
      is_online_ = is_online;
    }
  }

  void OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args) {
    // Request deferral of the suspending operation. This ensures that the app
    // does not immediately get suspended when this function returns.
    suspend_deferral_ = args->SuspendingOperation->GetDeferral();

    auto extended_resources_manager =
        shared::uwp::ExtendedResourcesManager::GetInstance();
    bool is_safe_to_suspend = extended_resources_manager->IsSafeToSuspend();

    // Request extended execution during which we will suspend the app and
    // release extended resources.
    auto session = ref new ExtendedExecutionSession();
    session->Reason = ExtendedExecutionReason::SavingData;
    session->Description = "Suspending...";

    // If the extended execution session gets revoked, we have to complete
    // the deferral.
    Windows::Foundation::EventRegistrationToken revoked_token =
        session->Revoked +=
        ref new TypedEventHandler<Object ^,
                                  ExtendedExecutionRevokedEventArgs ^>(
            this, &App::ExtendedExecutionSessionRevoked);
    Concurrency::create_task(session->RequestExtensionAsync())
        .then([this, is_safe_to_suspend,
               extended_resources_manager](ExtendedExecutionResult result) {
          // Suspend the app and release extended resources during the extended
          // session.

          // Note if we dispatch "suspend" here before pause, application.cc
          // will inject the "pause" which will cause us to go async which
          // will cause us to not have completed the suspend operation before
          // returning, which UWP requires.
          ApplicationUwp::Get()->DispatchAndDelete(
              new ApplicationUwp::Event(kSbEventTypeBlur, NULL, NULL));
          ApplicationUwp::Get()->DispatchAndDelete(
              new ApplicationUwp::Event(kSbEventTypeConceal, NULL, NULL));
          ApplicationUwp::Get()->DispatchAndDelete(
              new ApplicationUwp::Event(kSbEventTypeFreeze, NULL, NULL));
          extended_resources_manager->ReleaseExtendedResources();
          if (!extended_resources_manager->IsSafeToSuspend()) {
            ForceQuit();
          }
        })
        .then([this, is_safe_to_suspend, session, revoked_token]() {
          // The extended session has completed, we are ready to be suspended
          // now.
          session->Revoked -= revoked_token;
          delete session;

          CompleteSuspendDeferral();
        });
    if (!is_safe_to_suspend) {
      ForceQuit();
    }
  }

  void OnResuming(Platform::Object ^ sender, Platform::Object ^ args) {
    SB_LOG(INFO) << "Resuming application.";
    ApplicationUwp::Get()->DispatchAndDelete(
        new ApplicationUwp::Event(kSbEventTypeUnfreeze, NULL, NULL));
    ApplicationUwp::Get()->DispatchAndDelete(
        new ApplicationUwp::Event(kSbEventTypeReveal, NULL, NULL));
    ApplicationUwp::Get()->DispatchAndDelete(
        new ApplicationUwp::Event(kSbEventTypeFocus, NULL, NULL));
    shared::win32::DrmSystemOnUwpResume();
    shared::uwp::ExtendedResourcesManager::GetInstance()
        ->AcquireExtendedResources();
  }

  void OnKeyUp(CoreWindow ^ sender, KeyEventArgs ^ args) {
    ApplicationUwp::Get()->OnKeyEvent(sender, args, true);
  }

  void OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args) {
    ApplicationUwp::Get()->OnKeyEvent(sender, args, false);
  }

  void OnActivated(CoreApplicationView ^ application_view,
                   IActivatedEventArgs ^ args) {
    SB_LOG(INFO) << "OnActivated";
    shared::uwp::ExtendedResourcesManager::GetInstance()
        ->AcquireExtendedResources();

    std::string start_url = entry_point_;
    bool command_line_set = false;

    // Please see application lifecycle description:
    // https://docs.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
    // Note that this document was written for Xaml apps not core apps,
    // so for us the precise API is a little different.
    // The substance is that, while OnActivated is definitely called the
    // first time the application is started, it may additionally called
    // in other cases while the process is already running. Starboard
    // applications cannot fully restart in a process lifecycle,
    // so we interpret the first activation and the subsequent ones differently.
    if (args->Kind == ActivationKind::Protocol) {
      Uri ^ uri = dynamic_cast<IProtocolActivatedEventArgs ^>(args)->Uri;

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
      // The starboard: scheme provides commandline arguments, but that's
      // only allowed during a process's first activation.
      std::string scheme = platformStringToString(uri->SchemeName);
      if (!previously_activated_ && ends_with(scheme, "-starboard")) {
        std::string uri_string = wchar_tToUTF8(uri->RawUri->Data());
        // args_ is a vector of std::string, but argv_ is a vector of
        // char* into args_ so as to compose a char**.
        args_ = ParseStarboardUri(uri_string);
        for (const std::string& arg : args_) {
          argv_.push_back(arg.c_str());
        }

        ApplicationUwp::Get()->SetCommandLine(static_cast<int>(argv_.size()),
                                              argv_.data());
        command_line_set = true;
      }
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
      if (uri->SchemeName->Equals("youtube") ||
          uri->SchemeName->Equals("youtube-tv") ||
          uri->SchemeName->Equals("ms-xbl-07459769")) {
        std::string uri_string = platformStringToString(uri->RawUri);

        // Strip the protocol from the uri.
        size_t index = uri_string.find(':');
        if (index != std::string::npos) {
          uri_string = uri_string.substr(index + 1);
        }

        ProcessDeepLinkUri(&uri_string);
      }
    } else if (args->Kind == ActivationKind::DialReceiver) {
      DialReceiverActivatedEventArgs ^ dial_args =
          dynamic_cast<DialReceiverActivatedEventArgs ^>(args);
      SB_CHECK(dial_args);
      Platform::String ^ arguments = dial_args->Arguments;
      if (previously_activated_) {
        std::string uri_string =
            kDialParamPrefix + platformStringToString(arguments);
        ProcessDeepLinkUri(&uri_string);
      } else {
        std::string activation_args = "--url=";
        activation_args.append(start_url);
        activation_args.append("?");
        activation_args.append(platformStringToString(arguments));
        SB_DLOG(INFO) << "Dial Activation url: " << activation_args;
        args_.push_back(GetArgvZero());
        args_.push_back(activation_args);
        // Set partition URL in case start_url is the main app first run
        // special case.
        std::string partition_arg = "--local_storage_partition_url=";
        partition_arg.append(entry_point_);
        args_.push_back(partition_arg);
        for (const std::string& arg : args_) {
          argv_.push_back(arg.c_str());
        }
        ApplicationUwp::Get()->SetCommandLine(static_cast<int>(argv_.size()),
                                              argv_.data());
        command_line_set = true;
      }
    }
    previous_activation_kind_ = args->Kind;

    if (!previously_activated_) {
      if (!command_line_set) {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
        TryAddCommandArgsFromStarboardFile(&args_);
        CommandLine cmd_line(args_);
        if (cmd_line.HasSwitch(kNetArgsCommandSwitchWait)) {
          SbTime timeout = kSbTimeSecond * 2;
          std::string val = cmd_line.GetSwitchValue(kNetArgsCommandSwitchWait);
          if (!val.empty()) {
            timeout = atoi(val.c_str());
          }
          AddCommandArgsFromNetArgs(timeout, &args_);
        }
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)

        if (!CommandLine(args_).HasSwitch("url")) {
          args_.push_back(GetArgvZero());
          std::string start_url_arg = "--url=";
          start_url_arg.append(start_url);
          args_.push_back(start_url_arg);
          std::string partition_arg = "--local_storage_partition_url=";
          partition_arg.append(entry_point_);
          args_.push_back(partition_arg);
        }

        for (auto& arg : args_) {
          argv_.push_back(arg.c_str());
        }

        ApplicationUwp::Get()->SetCommandLine(static_cast<int>(argv_.size()),
                                              argv_.data());
      }

      ApplicationUwp* application_uwp = ApplicationUwp::Get();
      const CommandLine* command_line = application_uwp->GetCommandLine();

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
      if (command_line->HasSwitch(kWatchDogLog)) {
        // Launch a thread.
        std::string switch_val = command_line->GetSwitchValue(kWatchDogLog);
        auto uwp_dir =
            Windows::Storage::ApplicationData::Current->LocalCacheFolder;
        std::stringstream ss;
        ss << platformStringToString(uwp_dir->Path) << "/" << switch_val;
        shared::uwp::StartWatchdogLog(ss.str());
      }

      if (command_line->HasSwitch(kNetLogCommandSwitchWait)) {
        SbTime timeout = kSbTimeSecond;
        std::string val =
            command_line->GetSwitchValue(kNetLogCommandSwitchWait);
        if (!val.empty()) {
          timeout = atoi(val.c_str());
        }
        NetLogWaitForClientConnected(timeout);
      }

      if (command_line->HasSwitch(kLogPathSwitch)) {
        std::stringstream ss;
        ss << platformStringToString(
            Windows::Storage::ApplicationData::Current->LocalCacheFolder->Path);
        ss << "\\"
           << "" << command_line->GetSwitchValue(kLogPathSwitch);
        std::string full_path_log_file = ss.str();
        shared::uwp::OpenLogFileWin32(full_path_log_file.c_str());
      } else {
#if !defined(COBALT_BUILD_TYPE_GOLD)
        // Log to a file on the last removable device available (probably the
        // most recently added removable device).
        if (KnownFolders::RemovableDevices != nullptr) {
          concurrency::create_task(
              KnownFolders::RemovableDevices->GetFoldersAsync())
              .then(
                  [](concurrency::task<IVectorView<StorageFolder ^> ^> result) {
                    IVectorView<StorageFolder ^> ^ results;
                    try {
                      results = result.get();
                    } catch (Platform::Exception ^) {
                      SB_LOG(ERROR)
                          << "Unable to open log file in RemovableDevices";
                      return;
                    }

                    if (results->Size == 0) {
                      return;
                    }

                    StorageFolder ^ folder = results->GetAt(results->Size - 1);
                    Calendar ^ now = ref new Calendar();
                    char filename[128];
                    SbStringFormatF(filename, sizeof(filename),
                                    "cobalt_log_%04d%02d%02d_%02d%02d%02d.txt",
                                    now->Year, now->Month, now->Day,
                                    now->Hour + now->FirstHourInThisPeriod,
                                    now->Minute, now->Second);
                    shared::uwp::OpenLogFileUWP(folder, filename);
                  });
        }
#endif  // !defined(COBALT_BUILD_TYPE_GOLD)
      }
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
      SB_LOG(INFO) << "Starting " << GetBinaryName();

      CoreWindow::GetForCurrentThread()->Activate();
      // Call DispatchStart async so the UWP system thinks we're activated.
      // Some tools seem to want the application to be activated before
      // interacting with them, some things are disallowed during activation
      // (such as exiting), and DispatchStart (for example) runs
      // automated tests synchronously.
      RunInMainThreadAsync([this]() {
        ApplicationUwp::Get()->DispatchStart(application_start_time_);
      });
    }
    previously_activated_ = true;
  }

 private:
  void ProcessDeepLinkUri(std::string* uri_string) {
    SB_DCHECK(uri_string);
    if (previously_activated_) {
      std::unique_ptr<Application::Event> event =
          MakeDeepLinkEvent(*uri_string);
      SB_DCHECK(event);
      ApplicationUwp::Get()->Inject(event.release());
    } else {
      ApplicationUwp::Get()->SetStartLink(uri_string->c_str());
    }
  }

  std::string entry_point_;
  bool is_online_;
  bool previously_activated_;
  // Only valid if previously_activated_ is true
  ActivationKind previous_activation_kind_;
  std::vector<std::string> args_;
  std::vector<const char*> argv_;

  shared::uwp::ApplicationUwp application_;
  SuspendingDeferral ^ suspend_deferral_ = nullptr;
  SbTimeMonotonic application_start_time_;
};

ref class Direct3DApplicationSource sealed : IFrameworkViewSource {
 public:
  Direct3DApplicationSource(SbTimeMonotonic start_time)
      : application_start_time_{start_time} {}
  virtual IFrameworkView ^ CreateView() {
    return ref new App(application_start_time_);
  } private : SbTimeMonotonic application_start_time_;
};

namespace shared {
namespace uwp {

void DisplayStatusWatcher::CreateWatcher() {
  Platform::Collections::Vector<Platform::String ^> ^ requestedProperties =
      ref new Platform::Collections::Vector<Platform::String ^>();
  requestedProperties->Append("System.Devices.InterfaceClassGuid");
  requestedProperties->Append("System.ItemNameDisplay");
  watcher_ = DeviceInformation::CreateWatcher(
      const_cast<Platform::String ^>(kGenericPnpMonitorAqs),
      requestedProperties);
  SB_CHECK(watcher_);
  watcher_->Added +=
      ref new TypedEventHandler<DeviceWatcher ^, DeviceInformation ^>(
          &OnDeviceAdded);
  watcher_->Removed +=
      ref new TypedEventHandler<DeviceWatcher ^, DeviceInformationUpdate ^>(
          &OnDeviceRemoved);
  watcher_->Start();
}

bool DisplayStatusWatcher::IsWatcherStarted() {
  SB_CHECK(watcher_);
  DeviceWatcherStatus status = watcher_->Status;
  return (status == DeviceWatcherStatus::Started) ||
         (status == DeviceWatcherStatus::EnumerationCompleted);
}

void DisplayStatusWatcher::StopWatcher() {
  SB_CHECK(watcher_);
  if (IsWatcherStarted()) {
    watcher_->Stop();
  }
}

#if SB_API_VERSION >= 15
ApplicationUwp::ApplicationUwp(SbEventHandleCallback sb_event_handle_callback)
    : shared::starboard::Application(sb_event_handle_callback),
      window_(kSbWindowInvalid),
#else
ApplicationUwp::ApplicationUwp()
    : window_(kSbWindowInvalid),
#endif  // SB_API_VERSION >= 15
      localized_strings_(SbSystemGetLocaleId()),
      device_id_(MakeDeviceId()) {
  SbWindowOptions options;
  SbWindowSetDefaultOptions(&options);
  window_size_ = options.size;
  analog_thumbstick_thread_.reset(new AnalogThumbstickThread(this));
}

ApplicationUwp::~ApplicationUwp() {
  SB_CHECK(watcher_);
  {
    ScopedLock lock(time_event_mutex_);
    timer_event_map_.clear();
  }
  watcher_->StopWatcher();
  analog_thumbstick_thread_.reset(nullptr);
}

void ApplicationUwp::Initialize() {}

void ApplicationUwp::Teardown() {
  CloseWatchdogLog();
}

Application::Event* ApplicationUwp::GetNextEvent() {
  SB_NOTREACHED();
  return nullptr;
}

SbWindow ApplicationUwp::CreateWindowForUWP(const SbWindowOptions*) {
  // TODO: Determine why SB_DCHECK(IsCurrentThread()) fails in nplb, fix it,
  // and add back this check.

  if (SbWindowIsValid(window_)) {
    return kSbWindowInvalid;
  }

  if (!watcher_) {
    watcher_ = ref new shared::uwp::DisplayStatusWatcher();
    watcher_->CreateWatcher();
  }

  window_size_ = GetPreferredWindowSize();

  window_ = new SbWindowPrivate(window_size_.width, window_size_.height);
  return window_;
}

SbWindowSize ApplicationUwp::GetVisibleAreaSize() {
  SbWindowSize size{};
  if (SbWindowGetSize(window_, &size)) {
    return size;
  }
  return window_size_;
}

SbWindowSize ApplicationUwp::GetPreferredWindowSize() {
  bool scale_enabled = true;
  if (ApiInformation::IsApiContractPresent(
          "Windows.UI.ViewManagement.ViewManagementViewScalingContract", 1)) {
    // Use unscaled layout where possible
    scale_enabled = !ApplicationViewScaling::TrySetDisableLayoutScaling(true);
  }

  auto app_view = ApplicationView::GetForCurrentView();
  bool is_fullscreen = app_view->IsFullScreenMode;

  if (!is_fullscreen && scale_enabled &&
      ApiInformation::IsApiContractPresent(
          "Windows.Xbox.ApplicationResourcesContract", 1)) {
    // Always use full screen mode for XBox
    is_fullscreen = app_view->TryEnterFullScreenMode();
  }

  UpdateDisplayPreferredMode();
  int width = 0;
  int height = 0;
  auto display_mode = ApplicationUwp::Get()->GetPreferredModeHdr();
  if (!display_mode) {
    display_mode = ApplicationUwp::Get()->GetPreferredModeHdmi();
  }
  if (display_mode) {
    width = display_mode->ResolutionWidthInRawPixels;
    height = display_mode->ResolutionHeightInRawPixels;
  } else {
    auto bounds = app_view->VisibleBounds;
    auto scaleFactor =
        DisplayInformation::GetForCurrentView()->RawPixelsPerViewPixel;
    width = bounds.Width * scaleFactor;
    height = bounds.Height * scaleFactor;
  }
  SB_LOG(INFO) << "Preferred window size is " << width << " x " << height
               << "\nScaling is " << (scale_enabled ? "enabled" : "disabled")
               << "\nFull Screen mode is " << (is_fullscreen ? "ON" : "OFF");

  return SbWindowSize{width, height};
}

bool ApplicationUwp::DestroyWindow(SbWindow window) {
  // TODO: Determine why SB_DCHECK(IsCurrentThread()) fails in nplb, fix it,
  // and add back this check.

  if (!SbWindowIsValid(window)) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": Invalid context.";
    return false;
  }

  auto app_view = ApplicationView::GetForCurrentView();
  if (app_view->IsFullScreenMode &&
      ApiInformation::IsApiContractPresent(
          "Windows.Xbox.ApplicationResourcesContract", 1)) {
    app_view->ExitFullScreenMode();
  }

  SB_DCHECK(window_ == window);
  delete window;
  window_ = kSbWindowInvalid;

  return true;
}

void ApplicationUwp::UpdateDisplayPreferredMode() {
  ScopedLock lock(preferred_display_mode_mutex_);
  preferred_display_mode_hdmi_ = nullptr;
  preferred_display_mode_hdr_ = nullptr;
  if (!ApiInformation::IsTypePresent(
          "Windows.Graphics.Display.Core.HdmiDisplayInformation")) {
    return;
  }

  auto hdmi_display_info = HdmiDisplayInformation::GetForCurrentView();
  if (!hdmi_display_info) {
    return;
  }

  preferred_display_mode_hdmi_ = hdmi_display_info->GetCurrentDisplayMode();
  for (auto mode : hdmi_display_info->GetSupportedDisplayModes()) {
    if (mode->ResolutionWidthInRawPixels ==
            preferred_display_mode_hdmi_->ResolutionWidthInRawPixels &&
        mode->ResolutionHeightInRawPixels ==
            preferred_display_mode_hdmi_->ResolutionHeightInRawPixels &&
        mode->Is2086MetadataSupported && mode->IsSmpte2084Supported &&
        mode->BitsPerPixel >= kYuv420BitsPerPixelForHdr10Mode &&
        mode->ColorSpace == HdmiDisplayColorSpace::BT2020) {
      if (!preferred_display_mode_hdr_ ||
          preferred_display_mode_hdr_->RefreshRate < mode->RefreshRate) {
        preferred_display_mode_hdr_ = mode;
      }
    }
  }
}

bool ApplicationUwp::DispatchNextEvent() {
  core_window_->Activate();
  core_window_->Dispatcher->ProcessEvents(
      CoreProcessEventsOption::ProcessUntilQuit);
  return false;
}

Windows::Media::Protection::HdcpSession ^ ApplicationUwp::GetHdcpSession() {
  if (!hdcp_session_) {
    hdcp_session_ = ref new HdcpSession();
  }
  return hdcp_session_;
}

void ApplicationUwp::ResetHdcpSession() {
  // delete will call the destructor, but not free memory.
  // The destructor is called explicitly so that HDCP session can be
  // torn down immediately.
  if (hdcp_session_) {
    delete hdcp_session_;
    hdcp_session_ = nullptr;
  }
}

void ApplicationUwp::Inject(Application::Event* event) {
  RunInMainThreadAsync([this, event]() {
    bool result = DispatchAndDelete(event);
    if (!result) {
      NetLogFlushThenClose();
      CoreApplication::Exit();
    }
  });
}

void ApplicationUwp::InjectKeypress(SbKey key) {
  if (!SbWindowIsValid(window_)) {
    return;
  }
  std::unique_ptr<SbInputData> press_data(new SbInputData());
  std::unique_ptr<SbInputData> unpress_data(new SbInputData());

  memset(press_data.get(), 0, sizeof(*press_data));
  press_data->window = window_;
  press_data->device_type = kSbInputDeviceTypeKeyboard;
  press_data->device_id = device_id();
  press_data->key = key;
  press_data->type = kSbInputEventTypePress;

  *unpress_data = *press_data;
  unpress_data->type = kSbInputEventTypeUnpress;

  Inject(new Event(kSbEventTypeInput, press_data.release(),
                   &Application::DeleteDestructor<SbInputData>));
  Inject(new Event(kSbEventTypeInput, unpress_data.release(),
                   &Application::DeleteDestructor<SbInputData>));
}

void ApplicationUwp::InjectTimedEvent(Application::TimedEvent* timed_event) {
  SbTimeMonotonic delay_usec =
      timed_event->target_time - SbTimeGetMonotonicNow();
  if (delay_usec < 0) {
    delay_usec = 0;
  }

  // TimeSpan ticks are, like FILETIME, 100ns
  const SbTimeMonotonic kTicksPerUsec = 10;

  TimeSpan timespan;
  timespan.Duration = delay_usec * kTicksPerUsec;

  ScopedLock lock(time_event_mutex_);
  ThreadPoolTimer ^ timer = ThreadPoolTimer::CreateTimer(
      ref new TimerElapsedHandler([this, timed_event](ThreadPoolTimer ^ timer) {
        RunInMainThreadAsync([this, timed_event]() {
          // Even if the event is canceled, the callback can still fire.
          // Thus, the existence of event in timer_event_map_ is used
          // as a source of truth.
          std::size_t number_erased = 0;
          {
            ScopedLock lock(time_event_mutex_);
            number_erased = timer_event_map_.erase(timed_event->id);
          }
          if (number_erased > 0) {
            timed_event->callback(timed_event->context);
          }
        });
      }),
      timespan);
  timer_event_map_.emplace(timed_event->id, timer);
}

void ApplicationUwp::CancelTimedEvent(SbEventId event_id) {
  ScopedLock lock(time_event_mutex_);
  auto it = timer_event_map_.find(event_id);
  if (it == timer_event_map_.end()) {
    return;
  }
  it->second->Cancel();
  timer_event_map_.erase(it);
}

Application::TimedEvent* ApplicationUwp::GetNextDueTimedEvent() {
  SB_NOTIMPLEMENTED();
  return nullptr;
}

SbTimeMonotonic ApplicationUwp::GetNextTimedEventTargetTime() {
  SB_NOTIMPLEMENTED();
  return 0;
}

void ApplicationUwp::OnJoystickUpdate(SbKey key, SbInputVector input_vector) {
  if (!SbWindowIsValid(window_)) {
    return;
  }
  scoped_ptr<SbInputData> data(new SbInputData());
  memset(data.get(), 0, sizeof(*data));
  data->window = window_;
  data->type = kSbInputEventTypeMove;
  data->device_type = kSbInputDeviceTypeGamepad;
  data->device_id = device_id();
  data->key = key;
  data->character = 0;

  data->key_modifiers = kSbKeyModifiersNone;
  data->position = input_vector;

  SbKeyLocation key_location = kSbKeyLocationUnspecified;
  switch (key) {
    case kSbKeyGamepadLeftStickLeft:
    case kSbKeyGamepadLeftStickUp: {
      key_location = kSbKeyLocationLeft;
      break;
    }
    case kSbKeyGamepadRightStickLeft:
    case kSbKeyGamepadRightStickUp: {
      key_location = kSbKeyLocationRight;
      break;
    }
    default: {
      SB_NOTREACHED();
      break;
    }
  }

  data->key_location = key_location;
  Inject(new Event(kSbEventTypeInput, data.release(),
                   &Application::DeleteDestructor<SbInputData>));
}

Platform::String ^
    ApplicationUwp::GetString(const char* id, const char* fallback) const {
  return stringToPlatformString(localized_strings_.GetString(id, fallback));
}

bool ApplicationUwp::IsHdcpOn() {
  ScopedLock lock(hdcp_session_mutex_);

  return GetHdcpSession()->IsEffectiveProtectionAtLeast(kHDCPProtectionMode);
}

bool ApplicationUwp::TurnOnHdcp() {
  HdcpSetProtectionResult protection_result;
  {
    ScopedLock lock(hdcp_session_mutex_);

    protection_result = WaitForResult(
        GetHdcpSession()->SetDesiredMinProtectionAsync(kHDCPProtectionMode));
  }

  if (IsHdcpOn()) {
    return true;
  }

  // If the operation did not have intended result, log something.
  switch (protection_result) {
    case HdcpSetProtectionResult::Success:
      SB_LOG(INFO) << "Successfully set HDCP.";
      break;
    case HdcpSetProtectionResult::NotSupported:
      SB_LOG(INFO) << "HDCP is not supported.";
      break;
    case HdcpSetProtectionResult::TimedOut:
      SB_LOG(INFO) << "Setting HDCP timed out.";
      break;
    case HdcpSetProtectionResult::UnknownFailure:
      SB_LOG(INFO) << "Unknown failure returned while setting HDCP.";
      break;
  }

  return false;
}

bool ApplicationUwp::TurnOffHdcp() {
  {
    ScopedLock lock(hdcp_session_mutex_);
    ResetHdcpSession();
  }
  bool success = !IsHdcpOn();
  return success;
}

// TODO: Consolidate this function with TurnOfHdcp() and TurnOffHdcp().
bool ApplicationUwp::SetOutputProtection(bool should_enable_dhcp) {
  bool is_hdcp_on = IsHdcpOn();

  if (is_hdcp_on == should_enable_dhcp) {
    return true;
  }

  SB_LOG(INFO) << "Attempting to "
               << (should_enable_dhcp ? "enable" : "disable")
               << " output protection.  Current status: "
               << (is_hdcp_on ? "enabled" : "disabled");
  SbTimeMonotonic tick = SbTimeGetMonotonicNow();

  bool hdcp_success = false;
  if (should_enable_dhcp) {
    hdcp_success = TurnOnHdcp();
  } else {
    hdcp_success = TurnOffHdcp();
  }

  is_hdcp_on = (hdcp_success ? should_enable_dhcp : !should_enable_dhcp);

  SbTimeMonotonic tock = SbTimeGetMonotonicNow();
  SB_LOG(INFO) << "Output protection is "
               << (is_hdcp_on ? "enabled" : "disabled")
               << ".  Toggling HDCP took " << (tock - tick) / kSbTimeMillisecond
               << " milliseconds.";
  return hdcp_success;
}

Platform::Agile<Windows::UI::Core::CoreDispatcher> GetDispatcher() {
  return ApplicationUwp::Get()->GetDispatcher();
}

Platform::Agile<Windows::Media::SystemMediaTransportControls>
GetTransportControls() {
  return ApplicationUwp::Get()->GetTransportControls();
}

void DisplayRequestActive() {
  RunInMainThreadAsync([]() {
    if (display_request != nullptr) {
      display_request->RequestActive();
    }
  });
}

void DisplayRequestRelease() {
  RunInMainThreadAsync([]() {
    if (display_request != nullptr) {
      display_request->RequestRelease();
    }
  });
}

void InjectKeypress(SbKey key) {
  ApplicationUwp::Get()->InjectKeypress(key);
}

namespace {

// Calls CoreApplication::Run() on a new thread to free up the main thread.
// This allows all extended resources related operations to be run on the main
// thread.
class CoreApplicationThread : public ::starboard::Thread {
 public:
  explicit CoreApplicationThread(SbTimeMonotonic start_time)
      : application_start_time_{start_time}, Thread("core_app") {}
  void Run() override {
    CoreApplication::Run(
        ref new Direct3DApplicationSource(application_start_time_));
    ExtendedResourcesManager::GetInstance()->Quit();
  }

 private:
  SbTimeMonotonic application_start_time_;
};

}  // namespace

int InternalMain() {
  volatile auto start_time = SbTimeGetMonotonicNow();
  if (!IsDebuggerPresent()) {
    // By default, a Windows application will display a dialog box
    // when it crashes. This is extremely undesirable when run offline.
    // The following configures messages to be print to the console instead.
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  }

  WSAData wsaData;
  int init_result = WSAStartup(
      MAKEWORD(kWinSockVersionMajor, kWinSockVersionMajor), &wsaData);

  SB_CHECK(init_result == 0);
  // WSAStartup returns the highest version that is supported up to the version
  // we request.
  SB_CHECK(LOBYTE(wsaData.wVersion) == kWinSockVersionMajor &&
           HIBYTE(wsaData.wVersion) == kWinSockVersionMinor);

  HRESULT hr = MFStartup(MF_VERSION);
  SB_DCHECK(SUCCEEDED(hr));

#if defined(COBALT_BUILD_TYPE_GOLD)
  // Early exit for gold builds on desktop as a security measure.
#if SB_API_VERSION < 15
  if (SbSystemGetDeviceType() == kSbSystemDeviceTypeDesktopPC) {
    return main_return_value;
  }
#else
  if (GetSystemPropertyString(kSbSystemPropertyDeviceType) ==
      kSystemDeviceTypeDesktopPC) {
    return main_return_value;
  }
#endif
#endif  // defined(COBALT_BUILD_TYPE_GOLD)

  shared::win32::RegisterMainThread();

  ExtendedResourcesManager extended_resources_manager;
  CoreApplicationThread thread(start_time);

  thread.Start();
  extended_resources_manager.Run();

  NetLogFlushThenClose();
  CoreApplication::Exit();

  MFShutdown();
  WSACleanup();

  return main_return_value;
}

#if SB_API_VERSION >= 15
extern "C" int SbRunStarboardMain(int argc,
                                  char** argv,
                                  SbEventHandleCallback callback) {
  return ApplicationUwp::Get()->Run(argc, argv);
}
#endif  // SB_API_VERSION >= 15

}  // namespace uwp
}  // namespace shared
}  // namespace starboard

[Platform::MTAThread] int main(Platform::Array<Platform::String ^> ^ args) {
  return starboard::shared::uwp::InternalMain();
}
