// Copyright 2017 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 "services/shape_detection/face_detection_provider_win.h"

#include <windows.media.faceanalysis.h>

#include "base/bind.h"
#include "base/logging.h"
#include "base/scoped_generic.h"
#include "base/win/core_winrt_util.h"
#include "base/win/post_async_results.h"
#include "base/win/scoped_hstring.h"
#include "base/win/windows_version.h"
#include "mojo/public/cpp/bindings/strong_binding.h"

namespace shape_detection {

namespace {

using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Graphics::Imaging::BitmapPixelFormat;
using ABI::Windows::Graphics::Imaging::ISoftwareBitmapStatics;
using ABI::Windows::Media::FaceAnalysis::FaceDetector;
using ABI::Windows::Media::FaceAnalysis::IFaceDetector;
using ABI::Windows::Media::FaceAnalysis::IFaceDetectorStatics;

using base::win::GetActivationFactory;
using base::win::ScopedHString;
using Microsoft::WRL::ComPtr;

BitmapPixelFormat GetPreferredPixelFormat(IFaceDetectorStatics* factory) {
  static constexpr BitmapPixelFormat kFormats[] = {
      ABI::Windows::Graphics::Imaging::BitmapPixelFormat_Gray8,
      ABI::Windows::Graphics::Imaging::BitmapPixelFormat_Nv12};

  for (const auto& format : kFormats) {
    boolean is_supported = false;
    factory->IsBitmapPixelFormatSupported(format, &is_supported);
    if (is_supported)
      return format;
  }
  return ABI::Windows::Graphics::Imaging::BitmapPixelFormat_Unknown;
}

}  // namespace

void FaceDetectionProviderWin::CreateFaceDetection(
    shape_detection::mojom::FaceDetectionRequest request,
    shape_detection::mojom::FaceDetectorOptionsPtr options) {
  // FaceDetector class is only available in Win 10 onwards (v10.0.10240.0).
  if (base::win::GetVersion() < base::win::VERSION_WIN10) {
    DVLOG(1) << "FaceDetector not supported before Windows 10";
    return;
  }
  // Loads functions dynamically at runtime to prevent library dependencies.
  if (!(base::win::ResolveCoreWinRTDelayload() &&
        ScopedHString::ResolveCoreWinRTStringDelayload())) {
    DLOG(ERROR) << "Failed loading functions from combase.dll";
    return;
  }

  ComPtr<IFaceDetectorStatics> factory;
  HRESULT hr = GetActivationFactory<
      IFaceDetectorStatics,
      RuntimeClass_Windows_Media_FaceAnalysis_FaceDetector>(&factory);
  if (FAILED(hr)) {
    DLOG(ERROR) << "IFaceDetectorStatics factory failed: "
                << logging::SystemErrorCodeToString(hr);
    return;
  }

  boolean is_supported = false;
  factory->get_IsSupported(&is_supported);
  if (!is_supported)
    return;

  // In the current version, the FaceDetector class only supports images in
  // Gray8 or Nv12. Gray8 should be a good type but verify it against
  // FaceDetector’s supported formats.
  BitmapPixelFormat pixel_format = GetPreferredPixelFormat(factory.Get());
  if (pixel_format ==
      ABI::Windows::Graphics::Imaging::BitmapPixelFormat_Unknown) {
    return;
  }

  // Create an instance of FaceDetector asynchronously.
  ComPtr<IAsyncOperation<FaceDetector*>> async_op;
  hr = factory->CreateAsync(&async_op);
  if (FAILED(hr)) {
    DLOG(ERROR) << "Create FaceDetector failed: "
                << logging::SystemErrorCodeToString(hr);
    return;
  }

  // Use WeakPtr to bind the callback so that the once callback will not be run
  // if this object has been already destroyed.
  hr = base::win::PostAsyncResults(
      std::move(async_op),
      base::BindOnce(&FaceDetectionProviderWin::OnFaceDetectorCreated,
                     weak_factory_.GetWeakPtr(), std::move(request),
                     pixel_format));
  if (FAILED(hr)) {
    DLOG(ERROR) << "Begin async operation failed: "
                << logging::SystemErrorCodeToString(hr);
    return;
  }

  // When |provider| goes out of scope it will immediately close its end of
  // the message pipe, then the callback OnFaceDetectorCreated will be not
  // called. This prevents this object from being destroyed before the
  // AsyncOperation completes.
  binding_->PauseIncomingMethodCallProcessing();
}

FaceDetectionProviderWin::FaceDetectionProviderWin() : weak_factory_(this) {}

FaceDetectionProviderWin::~FaceDetectionProviderWin() = default;

void FaceDetectionProviderWin::OnFaceDetectorCreated(
    shape_detection::mojom::FaceDetectionRequest request,
    BitmapPixelFormat pixel_format,
    ComPtr<IFaceDetector> face_detector) {
  binding_->ResumeIncomingMethodCallProcessing();

  if (!face_detector)
    return;

  ComPtr<ISoftwareBitmapStatics> bitmap_factory;
  const HRESULT hr = GetActivationFactory<
      ISoftwareBitmapStatics,
      RuntimeClass_Windows_Graphics_Imaging_SoftwareBitmap>(&bitmap_factory);
  if (FAILED(hr)) {
    DLOG(ERROR) << "ISoftwareBitmapStatics factory failed: "
                << logging::SystemErrorCodeToString(hr);
    return;
  }

  auto impl = std::make_unique<FaceDetectionImplWin>(
      std::move(face_detector), std::move(bitmap_factory), pixel_format);
  auto* impl_ptr = impl.get();
  impl_ptr->SetBinding(
      mojo::MakeStrongBinding(std::move(impl), std::move(request)));
}

}  // namespace shape_detection
