// Copyright 2018 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 "media/capture/video/fuchsia/video_capture_device_factory_fuchsia.h"

#include <lib/sys/cpp/component_context.h>

#include "base/check_op.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/system/system_monitor.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "media/capture/video/fuchsia/video_capture_device_fuchsia.h"

namespace media {

// Helper class that calls GetIdentifier() and GetConfigurations() for a
// fuchsia::camera3::Device instance and stores the results afterwards.
class VideoCaptureDeviceFactoryFuchsia::DeviceConfigFetcher {
 public:
  DeviceConfigFetcher(uint64_t device_id, fuchsia::camera3::DevicePtr device)
      : device_id_(device_id), device_(std::move(device)) {
    device_.set_error_handler(
        fit::bind_member(this, &DeviceConfigFetcher::OnError));
  }

  void Fetch(base::OnceClosure on_fetched_callback) {
    DCHECK(device_);
    DCHECK(!have_results());
    DCHECK(!on_fetched_callback_);

    on_fetched_callback_ = std::move(on_fetched_callback);
    device_->GetIdentifier(
        fit::bind_member(this, &DeviceConfigFetcher::OnDescription));
    device_->GetConfigurations(
        fit::bind_member(this, &DeviceConfigFetcher::OnConfigurations));
  }

  ~DeviceConfigFetcher() = default;

  DeviceConfigFetcher(const DeviceConfigFetcher&) = delete;
  const DeviceConfigFetcher& operator=(const DeviceConfigFetcher&) = delete;

  bool is_pending() const { return !!device_; }
  bool have_results() const { return description_ && formats_; }
  bool is_usable() const { return device_ || have_results(); }

  uint64_t device_id() const { return device_id_; }
  const std::string& description() const { return description_.value(); }
  const VideoCaptureFormats& formats() const { return formats_.value(); }

 private:
  void OnError(zx_status_t status) {
    ZX_LOG(ERROR, status) << "fuchsia.camera3.Device disconnected";

    if (on_fetched_callback_)
      std::move(on_fetched_callback_).Run();
  }

  void OnDescription(fidl::StringPtr identifier) {
    description_ = identifier.value_or("");
    MaybeSignalDone();
  }

  void OnConfigurations(std::vector<fuchsia::camera3::Configuration> configs) {
    VideoCaptureFormats formats;
    for (auto& config : configs) {
      for (auto& props : config.streams) {
        VideoCaptureFormat format;
        format.frame_size = gfx::Size(props.image_format.display_width,
                                      props.image_format.display_height);
        format.frame_rate = static_cast<float>(props.frame_rate.numerator) /
                            props.frame_rate.denominator;
        format.pixel_format =
            VideoCaptureDeviceFuchsia::GetConvertedPixelFormat(
                props.image_format.pixel_format.type);
        if (format.pixel_format == PIXEL_FORMAT_UNKNOWN)
          continue;
        formats.push_back(format);
      }
    }

    formats_ = std::move(formats);
    MaybeSignalDone();
  }

  void MaybeSignalDone() {
    if (!have_results())
      return;

    device_.Unbind();

    std::move(on_fetched_callback_).Run();
  }

  uint64_t device_id_;
  fuchsia::camera3::DevicePtr device_;
  absl::optional<std::string> description_;
  absl::optional<VideoCaptureFormats> formats_;
  base::OnceClosure on_fetched_callback_;
};

VideoCaptureDeviceFactoryFuchsia::VideoCaptureDeviceFactoryFuchsia() {
  DETACH_FROM_THREAD(thread_checker_);
}

VideoCaptureDeviceFactoryFuchsia::~VideoCaptureDeviceFactoryFuchsia() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}

std::unique_ptr<VideoCaptureDevice>
VideoCaptureDeviceFactoryFuchsia::CreateDevice(
    const VideoCaptureDeviceDescriptor& device_descriptor) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  uint64_t device_id;
  bool converted =
      base::StringToUint64(device_descriptor.device_id, &device_id);

  // Test may call CreateDevice() with an invalid |device_id|.
  if (!converted)
    return nullptr;

  // CreateDevice() may be called before GetDeviceDescriptors(). Make sure
  // |device_watcher_| is initialized.
  if (!device_watcher_)
    Initialize();

  fidl::InterfaceHandle<fuchsia::camera3::Device> device;
  device_watcher_->ConnectToDevice(device_id, device.NewRequest());
  return std::make_unique<VideoCaptureDeviceFuchsia>(std::move(device));
}

void VideoCaptureDeviceFactoryFuchsia::GetDevicesInfo(
    GetDevicesInfoCallback callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // If the list hasn't been received, then wait until it's received.
  if (!devices_ || num_pending_device_info_requests_) {
    pending_devices_info_requests_.push_back(std::move(callback));

    if (!device_watcher_)
      Initialize();

    return;
  }

  std::move(callback).Run(MakeDevicesInfo());
}

void VideoCaptureDeviceFactoryFuchsia::Initialize() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(!device_watcher_);
  DCHECK(!devices_);

  base::ComponentContextForProcess()->svc()->Connect(
      device_watcher_.NewRequest());

  device_watcher_.set_error_handler(fit::bind_member(
      this, &VideoCaptureDeviceFactoryFuchsia::OnDeviceWatcherDisconnected));

  WatchDevices();
}

void VideoCaptureDeviceFactoryFuchsia::OnDeviceWatcherDisconnected(
    zx_status_t status) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // CastRunner may close the channel with ZX_ERR_UNAVAILABLE error code when
  // none of the running applications have access to camera. No need to log the
  // error in that case.
  if (status != ZX_ERR_UNAVAILABLE)
    ZX_LOG(ERROR, status) << "fuchsia.camera3.DeviceWatcher disconnected.";

  // Clear the list of devices, so we don't report any camera devices while
  // DeviceWatcher is disconnected. We will try connecting DeviceWatcher again
  // when GetDevicesInfo() is called.
  devices_ = absl::nullopt;
  num_pending_device_info_requests_ = 0;

  MaybeResolvePendingDeviceInfoCallbacks();
}

void VideoCaptureDeviceFactoryFuchsia::WatchDevices() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  device_watcher_->WatchDevices(fit::bind_member(
      this, &VideoCaptureDeviceFactoryFuchsia::OnWatchDevicesResult));
}

void VideoCaptureDeviceFactoryFuchsia::OnWatchDevicesResult(
    std::vector<fuchsia::camera3::WatchDevicesEvent> events) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (!devices_)
    devices_.emplace();

  for (auto& e : events) {
    if (e.is_removed()) {
      auto it = devices_->find(e.removed());
      if (it == devices_->end()) {
        LOG(WARNING) << "Received device removed event for a device that "
                        "wasn't previously registered.";
        continue;
      }
      if (it->second->is_pending()) {
        // If the device info request was still pending then consider it
        // complete now. If this was the only device in pending state then all
        // callbacks will be resolved in
        // MaybeResolvePendingDeviceInfoCallbacks() called below.
        DCHECK_GT(num_pending_device_info_requests_, 0U);
        num_pending_device_info_requests_--;
      }
      devices_->erase(it);
      continue;
    }

    uint64_t id;
    if (e.is_added()) {
      id = e.added();
      if (devices_->find(id) != devices_->end()) {
        LOG(WARNING) << "Received device added event for a device that was "
                        "previously registered.";
        continue;
      }
    } else {
      id = e.existing();
      if (devices_->find(id) != devices_->end()) {
        continue;
      }
      LOG(WARNING) << "Received device exists event for a device that wasn't "
                      "previously registered.";
    }

    fuchsia::camera3::DevicePtr device;
    device_watcher_->ConnectToDevice(id, device.NewRequest());

    auto fetcher = std::make_unique<DeviceConfigFetcher>(id, std::move(device));

    // base::Unretained() is safe because the |fetcher| is owned by |this|.
    fetcher->Fetch(
        base::BindOnce(&VideoCaptureDeviceFactoryFuchsia::OnDeviceInfoFetched,
                       base::Unretained(this)));
    num_pending_device_info_requests_++;

    devices_->emplace(id, std::move(fetcher));
  }

  // Watch for further updates.
  WatchDevices();

  // Calls callbacks, which may delete |this|.
  MaybeResolvePendingDeviceInfoCallbacks();
}

void VideoCaptureDeviceFactoryFuchsia::OnDeviceInfoFetched() {
  DCHECK_GT(num_pending_device_info_requests_, 0U);
  num_pending_device_info_requests_--;
  MaybeResolvePendingDeviceInfoCallbacks();
}

std::vector<VideoCaptureDeviceInfo>
VideoCaptureDeviceFactoryFuchsia::MakeDevicesInfo() {
  std::vector<VideoCaptureDeviceInfo> devices_info;
  // Leave the list empty if |devices_| isn't set (e.g. after DeviceWatcher
  // has disconnected).
  if (devices_) {
    for (auto& device : devices_.value()) {
      DCHECK(!device.second->is_pending());
      if (device.second->is_usable()) {
        devices_info.emplace_back(VideoCaptureDeviceDescriptor(
            device.second->description(), base::NumberToString(device.first),
            VideoCaptureApi::FUCHSIA_CAMERA3));
        devices_info.back().supported_formats = device.second->formats();
      }
    }
  }
  return devices_info;
}

void VideoCaptureDeviceFactoryFuchsia::
    MaybeResolvePendingDeviceInfoCallbacks() {
  if (num_pending_device_info_requests_ > 0)
    return;

  // Notify system monitor if devices have changed. This will indirectly update
  // media device manager and the web app eventually.
  auto* system_monitor = base::SystemMonitor::Get();
  if (system_monitor) {
    system_monitor->ProcessDevicesChanged(
        base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
  }

  std::vector<GetDevicesInfoCallback> callbacks;
  callbacks.swap(pending_devices_info_requests_);

  auto weak_this = weak_factory_.GetWeakPtr();
  for (auto& c : callbacks) {
    auto devices_info = MakeDevicesInfo();
    std::move(c).Run(devices_info);
    if (!weak_this)
      return;
  }
}

}  // namespace media
