// 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/android/video_capture_device_factory_android.h"

#include <utility>

#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/containers/cxx20_erase.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "media/capture/video/android/capture_jni_headers/VideoCaptureFactory_jni.h"
#include "media/capture/video/android/video_capture_device_android.h"

using base::android::AttachCurrentThread;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;

namespace media {

// static
ScopedJavaLocalRef<jobject>
VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid(
    int id,
    jlong nativeVideoCaptureDeviceAndroid) {
  return (Java_VideoCaptureFactory_createVideoCapture(
      AttachCurrentThread(), id, nativeVideoCaptureDeviceAndroid));
}

VideoCaptureDeviceFactoryAndroid::VideoCaptureDeviceFactoryAndroid() = default;
VideoCaptureDeviceFactoryAndroid::~VideoCaptureDeviceFactoryAndroid() = default;

std::unique_ptr<VideoCaptureDevice>
VideoCaptureDeviceFactoryAndroid::CreateDevice(
    const VideoCaptureDeviceDescriptor& device_descriptor) {
  DCHECK(thread_checker_.CalledOnValidThread());
  int id;
  if (!base::StringToInt(device_descriptor.device_id, &id))
    return nullptr;

  std::unique_ptr<VideoCaptureDeviceAndroid> video_capture_device(
      new VideoCaptureDeviceAndroid(device_descriptor));

  if (video_capture_device->Init()) {
    if (test_mode_)
      video_capture_device->ConfigureForTesting();
    return std::move(video_capture_device);
  }

  DLOG(ERROR) << "Error creating Video Capture Device.";
  return nullptr;
}

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

  JNIEnv* env = AttachCurrentThread();

  const int num_cameras = Java_VideoCaptureFactory_getNumberOfCameras(env);
  DVLOG(1) << __func__ << ": num_cameras=" << num_cameras;
  if (num_cameras <= 0) {
    std::move(callback).Run({});
    return;
  }

  std::vector<VideoCaptureDeviceInfo> devices_info;
  for (int camera_index = num_cameras - 1; camera_index >= 0; --camera_index) {
    base::android::ScopedJavaLocalRef<jstring> device_name =
        Java_VideoCaptureFactory_getDeviceName(env, camera_index);
    if (device_name.obj() == nullptr)
      continue;
    const std::string display_name =
        base::android::ConvertJavaStringToUTF8(device_name);

    base::android::ScopedJavaLocalRef<jstring> device_id_jstring =
        Java_VideoCaptureFactory_getDeviceId(env, camera_index);
    if (device_id_jstring.obj() == nullptr)
      continue;
    const std::string device_id =
        base::android::ConvertJavaStringToUTF8(device_id_jstring);

    const VideoCaptureApi capture_api_type = static_cast<VideoCaptureApi>(
        Java_VideoCaptureFactory_getCaptureApiType(env, camera_index));
    if (capture_api_type == VideoCaptureApi::UNKNOWN)
      continue;
    VideoCaptureControlSupport control_support;
    const int facing_mode =
        Java_VideoCaptureFactory_getFacingMode(env, camera_index);

    auto zoom_it = zooms_cache_.find(device_id);
    if (zoom_it != zooms_cache_.end()) {
      control_support.zoom = zoom_it->second;
    } else {
      control_support.zoom =
          Java_VideoCaptureFactory_isZoomSupported(env, camera_index);
      zooms_cache_.emplace(device_id, control_support.zoom);
    }

    // Android cameras are not typically USB devices, and the model_id is
    // currently only used for USB model identifiers, so this implementation
    // just indicates an unknown device model (by not providing one).
    VideoCaptureDeviceInfo device_info(VideoCaptureDeviceDescriptor(
        display_name, device_id, "" /*model_id*/, capture_api_type,
        control_support, VideoCaptureTransportType::OTHER_TRANSPORT,
        static_cast<VideoFacingMode>(facing_mode)));

    auto it = supported_formats_cache_.find(device_id);
    if (it != supported_formats_cache_.end()) {
      device_info.supported_formats = it->second;
    } else {
      device_info.supported_formats =
          GetSupportedFormats(camera_index, display_name);
      supported_formats_cache_.emplace(device_id,
                                       device_info.supported_formats);
    }

    // We put user-facing devices to the front of the list in order to make
    // them by-default preferred over environment-facing ones when no other
    // constraints for device selection are given.
    if (facing_mode == MEDIA_VIDEO_FACING_USER) {
      devices_info.insert(devices_info.begin(), std::move(device_info));
    } else {
      devices_info.emplace_back(std::move(device_info));
    }

    DVLOG(1) << __func__ << ": camera "
             << "device_name=" << display_name << ", unique_id=" << device_id;
  }

  // Remove old entries from |supported_formats_cache_| if necessary.
  if (supported_formats_cache_.size() > devices_info.size()) {
    base::EraseIf(supported_formats_cache_, [&devices_info](const auto& entry) {
      return base::ranges::none_of(
          devices_info, [&entry](const VideoCaptureDeviceInfo& info) {
            return entry.first == info.descriptor.device_id;
          });
    });
  }

  // Remove old entries from |zooms_cache_| if necessary.
  if (zooms_cache_.size() > devices_info.size()) {
    base::EraseIf(zooms_cache_, [&devices_info](const auto& entry) {
      return base::ranges::none_of(
          devices_info, [&entry](const VideoCaptureDeviceInfo& info) {
            return entry.first == info.descriptor.device_id;
          });
    });
  }

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

VideoCaptureFormats VideoCaptureDeviceFactoryAndroid::GetSupportedFormats(
    int device_index,
    const std::string& display_name) {
  DCHECK(thread_checker_.CalledOnValidThread());

  JNIEnv* env = AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jobjectArray> collected_formats =
      Java_VideoCaptureFactory_getDeviceSupportedFormats(env, device_index);
  if (collected_formats.is_null())
    return {};

  VideoCaptureFormats capture_formats;
  for (auto format : collected_formats.ReadElements<jobject>()) {
    VideoPixelFormat pixel_format = PIXEL_FORMAT_UNKNOWN;
    switch (Java_VideoCaptureFactory_getCaptureFormatPixelFormat(env, format)) {
      case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_YV12:
        pixel_format = PIXEL_FORMAT_YV12;
        break;
      case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_NV21:
        pixel_format = PIXEL_FORMAT_NV21;
        break;
      case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_YUV_420_888:
        pixel_format = PIXEL_FORMAT_I420;
        break;
      default:
        // TODO(crbug.com/792260): break here and let the enumeration continue
        // with UNKNOWN pixel format because the platform doesn't know until
        // capture, but some unrelated tests timeout https://crbug.com/644910.
        continue;
    }
    VideoCaptureFormat capture_format(
        gfx::Size(Java_VideoCaptureFactory_getCaptureFormatWidth(env, format),
                  Java_VideoCaptureFactory_getCaptureFormatHeight(env, format)),
        Java_VideoCaptureFactory_getCaptureFormatFramerate(env, format),
        pixel_format);
    DVLOG(1) << display_name << " "
             << VideoCaptureFormat::ToString(capture_format);
    capture_formats.push_back(std::move(capture_format));
  }

  return capture_formats;
}

bool VideoCaptureDeviceFactoryAndroid::IsLegacyOrDeprecatedDevice(
    const std::string& device_id) {
  int id;
  if (!base::StringToInt(device_id, &id))
    return true;
  return (Java_VideoCaptureFactory_isLegacyOrDeprecatedDevice(
      AttachCurrentThread(), id));
}

}  // namespace media
