// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/vr/vr_device_manager.h"

#include <utility>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/singleton.h"
#include "build/build_config.h"

#if defined(OS_ANDROID)
#include "device/vr/android/gvr/gvr_device_provider.h"
#endif

namespace device {

namespace {
VRDeviceManager* g_vr_device_manager = nullptr;
}

VRDeviceManager::VRDeviceManager()
    : vr_initialized_(false), keep_alive_(false), has_scheduled_poll_(false) {
// Register VRDeviceProviders for the current platform
#if defined(OS_ANDROID)
  RegisterProvider(base::WrapUnique(new GvrDeviceProvider()));
#endif
}

VRDeviceManager::VRDeviceManager(std::unique_ptr<VRDeviceProvider> provider)
    : vr_initialized_(false), keep_alive_(true), has_scheduled_poll_(false) {
  thread_checker_.DetachFromThread();
  RegisterProvider(std::move(provider));
  SetInstance(this);
}

VRDeviceManager::~VRDeviceManager() {
  DCHECK(thread_checker_.CalledOnValidThread());
  StopSchedulingPollEvents();
  g_vr_device_manager = nullptr;
}

VRDeviceManager* VRDeviceManager::GetInstance() {
  if (!g_vr_device_manager)
    g_vr_device_manager = new VRDeviceManager();
  return g_vr_device_manager;
}

void VRDeviceManager::SetInstance(VRDeviceManager* instance) {
  // Unit tests can create multiple instances but only one should exist at any
  // given time so g_vr_device_manager should only go from nullptr to
  // non-nullptr and vica versa.
  CHECK_NE(!!instance, !!g_vr_device_manager);
  g_vr_device_manager = instance;
}

bool VRDeviceManager::HasInstance() {
  // For testing. Checks to see if a VRDeviceManager instance is active.
  return !!g_vr_device_manager;
}

void VRDeviceManager::AddService(VRServiceImpl* service) {
  services_.push_back(service);

  // Ensure that the device providers are initialized
  InitializeProviders();
}

void VRDeviceManager::RemoveService(VRServiceImpl* service) {
  services_.erase(std::remove(services_.begin(), services_.end(), service),
                  services_.end());

  if (services_.empty() && !keep_alive_) {
    // Delete the device manager when it has no active connections.
    delete g_vr_device_manager;
  }
}

mojo::Array<VRDisplayPtr> VRDeviceManager::GetVRDevices() {
  DCHECK(thread_checker_.CalledOnValidThread());

  InitializeProviders();

  std::vector<VRDevice*> devices;
  for (const auto& provider : providers_)
    provider->GetDevices(&devices);

  mojo::Array<VRDisplayPtr> out_devices;
  for (auto* device : devices) {
    if (device->id() == VR_DEVICE_LAST_ID)
      continue;

    if (devices_.find(device->id()) == devices_.end())
      devices_[device->id()] = device;

    VRDisplayPtr vr_device_info = device->GetVRDevice();
    if (vr_device_info.is_null())
      continue;

    vr_device_info->index = device->id();
    out_devices.push_back(std::move(vr_device_info));
  }

  return out_devices;
}

VRDevice* VRDeviceManager::GetDevice(unsigned int index) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (index == 0) {
    return NULL;
  }

  DeviceMap::iterator iter = devices_.find(index);
  if (iter == devices_.end()) {
    return nullptr;
  }
  return iter->second;
}

// These dispatchers must use Clone() instead of std::move to ensure that
// if there are multiple registered services they all get a copy of the data.
void VRDeviceManager::OnDeviceChanged(VRDisplayPtr device) {
  for (const auto& service : services_)
    service->client()->OnDisplayChanged(device.Clone());
}

void VRDeviceManager::InitializeProviders() {
  if (vr_initialized_) {
    return;
  }

  for (const auto& provider : providers_)
    provider->Initialize();

  vr_initialized_ = true;
}

void VRDeviceManager::RegisterProvider(
    std::unique_ptr<VRDeviceProvider> provider) {
  providers_.push_back(make_linked_ptr(provider.release()));
}

void VRDeviceManager::SchedulePollEvents() {
  if (has_scheduled_poll_)
    return;

  has_scheduled_poll_ = true;

  timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(500), this,
               &VRDeviceManager::PollEvents);
}

void VRDeviceManager::PollEvents() {
  for (const auto& provider : providers_)
    provider->PollEvents();
}

void VRDeviceManager::StopSchedulingPollEvents() {
  if (has_scheduled_poll_)
    timer_.Stop();
}

}  // namespace device
