// Copyright 2014 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/mac/video_capture_device_factory_mac.h"

#import <IOKit/audio/IOAudioTypes.h>
#include <stddef.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/cxx17_backports.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task_runner_util.h"
#import "media/capture/video/mac/video_capture_device_avfoundation_mac.h"
#import "media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h"
#import "media/capture/video/mac/video_capture_device_decklink_mac.h"
#include "media/capture/video/mac/video_capture_device_mac.h"
#include "services/video_capture/public/uma/video_capture_service_event.h"

namespace {

void EnsureRunsOnCFRunLoopEnabledThread() {
  static bool has_checked_cfrunloop_for_video_capture = false;
  if (!has_checked_cfrunloop_for_video_capture) {
    base::ScopedCFTypeRef<CFRunLoopMode> mode(
        CFRunLoopCopyCurrentMode(CFRunLoopGetCurrent()));
    CHECK(mode != NULL)
        << "The MacOS video capture code must be run on a CFRunLoop-enabled "
           "thread";
    has_checked_cfrunloop_for_video_capture = true;
  }
}

media::VideoCaptureFormats GetDeviceSupportedFormats(
    const media::VideoCaptureDeviceDescriptor& descriptor) {
  media::VideoCaptureFormats formats;
  NSArray* devices = [AVCaptureDevice devices];
  AVCaptureDevice* device = nil;
  for (device in devices) {
    if (base::SysNSStringToUTF8([device uniqueID]) == descriptor.device_id)
      break;
  }
  if (device == nil)
    return media::VideoCaptureFormats();
  for (AVCaptureDeviceFormat* format in device.formats) {
    // MediaSubType is a CMPixelFormatType but can be used as CVPixelFormatType
    // as well according to CMFormatDescription.h
    const media::VideoPixelFormat pixelFormat = [VideoCaptureDeviceAVFoundation
        FourCCToChromiumPixelFormat:CMFormatDescriptionGetMediaSubType(
                                        [format formatDescription])];

    CMVideoDimensions dimensions =
        CMVideoFormatDescriptionGetDimensions([format formatDescription]);

    for (AVFrameRateRange* frameRate in
         [format videoSupportedFrameRateRanges]) {
      media::VideoCaptureFormat format(
          gfx::Size(dimensions.width, dimensions.height),
          frameRate.maxFrameRate, pixelFormat);
      DVLOG(2) << descriptor.display_name() << " "
               << media::VideoCaptureFormat::ToString(format);
      formats.push_back(std::move(format));
    }
  }
  return formats;
}

// Blocked devices are identified by a characteristic trailing substring of
// uniqueId. At the moment these are just Blackmagic devices.
const char* kBlockedCamerasIdSignature[] = {"-01FDA82C8A9C"};

int32_t get_device_descriptors_retry_count = 0;

}  // anonymous namespace

namespace media {

static bool IsDeviceBlocked(const VideoCaptureDeviceDescriptor& descriptor) {
  bool is_device_blocked = false;
  for (size_t i = 0;
       !is_device_blocked && i < base::size(kBlockedCamerasIdSignature); ++i) {
    is_device_blocked =
        base::EndsWith(descriptor.device_id, kBlockedCamerasIdSignature[i],
                       base::CompareCase::INSENSITIVE_ASCII);
  }
  DVLOG_IF(2, is_device_blocked)
      << "Blocked camera: " << descriptor.display_name()
      << ", id: " << descriptor.device_id;
  return is_device_blocked;
}

VideoCaptureDeviceFactoryMac::VideoCaptureDeviceFactoryMac() {
  thread_checker_.DetachFromThread();
}

VideoCaptureDeviceFactoryMac::~VideoCaptureDeviceFactoryMac() {
}

// static
void VideoCaptureDeviceFactoryMac::SetGetDevicesInfoRetryCount(int count) {
  get_device_descriptors_retry_count = count;
}

// static
int VideoCaptureDeviceFactoryMac::GetGetDevicesInfoRetryCount() {
  return get_device_descriptors_retry_count;
}

std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryMac::CreateDevice(
    const VideoCaptureDeviceDescriptor& descriptor) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(descriptor.capture_api, VideoCaptureApi::UNKNOWN);
  EnsureRunsOnCFRunLoopEnabledThread();

  std::unique_ptr<VideoCaptureDevice> capture_device;
  if (descriptor.capture_api == VideoCaptureApi::MACOSX_DECKLINK) {
    capture_device =
        std::make_unique<VideoCaptureDeviceDeckLinkMac>(descriptor);
  } else {
    VideoCaptureDeviceMac* device = new VideoCaptureDeviceMac(descriptor);
    capture_device.reset(device);
    if (!device->Init(descriptor.capture_api)) {
      LOG(ERROR) << "Could not initialize VideoCaptureDevice.";
      capture_device.reset();
    }
  }
  return std::unique_ptr<VideoCaptureDevice>(std::move(capture_device));
}

void VideoCaptureDeviceFactoryMac::GetDevicesInfo(
    GetDevicesInfoCallback callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  EnsureRunsOnCFRunLoopEnabledThread();

  // Loop through all available devices and add to |devices_info|.
  std::vector<VideoCaptureDeviceInfo> devices_info;
  DVLOG(1) << "Enumerating video capture devices using AVFoundation";
  base::scoped_nsobject<NSDictionary> capture_devices =
      GetVideoCaptureDeviceNames();
  // Enumerate all devices found by AVFoundation, translate the info for each
  // to class Name and add it to |device_names|.
  for (NSString* key in capture_devices.get()) {
    const std::string device_id = [key UTF8String];
    const VideoCaptureApi capture_api = VideoCaptureApi::MACOSX_AVFOUNDATION;
    int transport_type = [[capture_devices valueForKey:key] transportType];
    // Transport types are defined for Audio devices and reused for video.
    VideoCaptureTransportType device_transport_type =
        (transport_type == kIOAudioDeviceTransportTypeBuiltIn ||
         transport_type == kIOAudioDeviceTransportTypeUSB)
            ? VideoCaptureTransportType::MACOSX_USB_OR_BUILT_IN
            : VideoCaptureTransportType::OTHER_TRANSPORT;
    const std::string model_id = VideoCaptureDeviceMac::GetDeviceModelId(
        device_id, capture_api, device_transport_type);
    const VideoCaptureControlSupport control_support =
        VideoCaptureDeviceMac::GetControlSupport(model_id);
    VideoCaptureDeviceDescriptor descriptor(
        [[[capture_devices valueForKey:key] deviceName] UTF8String], device_id,
        model_id, capture_api, control_support, device_transport_type);
    if (IsDeviceBlocked(descriptor))
      continue;
    devices_info.emplace_back(descriptor);

    // Get supported formats
    devices_info.back().supported_formats =
        GetDeviceSupportedFormats(descriptor);
  }

  // Also retrieve Blackmagic devices, if present, via DeckLink SDK API.
  VideoCaptureDeviceDeckLinkMac::EnumerateDevices(&devices_info);

  if ([capture_devices count] > 0 && devices_info.empty()) {
    video_capture::uma::LogMacbookRetryGetDeviceInfosEvent(
        video_capture::uma::AVF_DROPPED_DESCRIPTORS_AT_FACTORY);
  }

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

}  // namespace media
