// Copyright 2013 The Flutter 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 "flutter/lib/ui/painting/image_descriptor.h"

#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "flutter/lib/ui/painting/multi_frame_codec.h"
#include "flutter/lib/ui/painting/single_frame_codec.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "third_party/tonic/dart_binding_macros.h"
#include "third_party/tonic/logging/dart_invoke.h"

namespace flutter {

IMPLEMENT_WRAPPERTYPEINFO(ui, ImageDescriptor);

const SkImageInfo ImageDescriptor::CreateImageInfo() const {
  FML_DCHECK(generator_);
  return generator_->GetInfo();
}

ImageDescriptor::ImageDescriptor(sk_sp<SkData> buffer,
                                 const SkImageInfo& image_info,
                                 std::optional<size_t> row_bytes)
    : buffer_(std::move(buffer)),
      generator_(nullptr),
      image_info_(image_info),
      row_bytes_(row_bytes) {}

ImageDescriptor::ImageDescriptor(sk_sp<SkData> buffer,
                                 std::shared_ptr<ImageGenerator> generator)
    : buffer_(std::move(buffer)),
      generator_(std::move(generator)),
      image_info_(CreateImageInfo()),
      row_bytes_(std::nullopt) {}

Dart_Handle ImageDescriptor::initEncoded(Dart_Handle descriptor_handle,
                                         ImmutableBuffer* immutable_buffer,
                                         Dart_Handle callback_handle) {
  if (!Dart_IsClosure(callback_handle)) {
    return tonic::ToDart("Callback must be a function");
  }

  if (!immutable_buffer) {
    return tonic::ToDart("Buffer parameter must not be null");
  }

  // This has to be valid because this method is called from Dart.
  auto dart_state = UIDartState::Current();
  auto registry = dart_state->GetImageGeneratorRegistry();

  if (!registry) {
    return tonic::ToDart(
        "Failed to access the internal image decoder "
        "registry on this isolate. Please file a bug on "
        "https://github.com/flutter/flutter/issues.");
  }

  auto generator =
      registry->CreateCompatibleGenerator(immutable_buffer->data());

  if (!generator) {
    // No compatible image decoder was found.
    return tonic::ToDart("Invalid image data");
  }

  auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
      immutable_buffer->data(), std::move(generator));

  FML_DCHECK(descriptor);

  descriptor->AssociateWithDartWrapper(descriptor_handle);
  tonic::DartInvoke(callback_handle, {Dart_TypeVoid()});

  return Dart_Null();
}

void ImageDescriptor::initRaw(Dart_Handle descriptor_handle,
                              const fml::RefPtr<ImmutableBuffer>& data,
                              int width,
                              int height,
                              int row_bytes,
                              PixelFormat pixel_format) {
  SkColorType color_type = kUnknown_SkColorType;
  switch (pixel_format) {
    case PixelFormat::kRGBA8888:
      color_type = kRGBA_8888_SkColorType;
      break;
    case PixelFormat::kBGRA8888:
      color_type = kBGRA_8888_SkColorType;
      break;
  }
  FML_DCHECK(color_type != kUnknown_SkColorType);
  auto image_info =
      SkImageInfo::Make(width, height, color_type, kPremul_SkAlphaType);
  auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
      data->data(), std::move(image_info),
      row_bytes == -1 ? std::nullopt : std::optional<size_t>(row_bytes));
  descriptor->AssociateWithDartWrapper(descriptor_handle);
}

void ImageDescriptor::instantiateCodec(Dart_Handle codec_handle,
                                       int target_width,
                                       int target_height) {
  fml::RefPtr<Codec> ui_codec;
  if (!generator_ || generator_->GetFrameCount() == 1) {
    ui_codec = fml::MakeRefCounted<SingleFrameCodec>(
        static_cast<fml::RefPtr<ImageDescriptor>>(this), target_width,
        target_height);
  } else {
    ui_codec = fml::MakeRefCounted<MultiFrameCodec>(generator_);
  }
  ui_codec->AssociateWithDartWrapper(codec_handle);
}

sk_sp<SkImage> ImageDescriptor::image() const {
  return generator_->GetImage();
}

bool ImageDescriptor::get_pixels(const SkPixmap& pixmap) const {
  FML_DCHECK(generator_);
  return generator_->GetPixels(pixmap.info(), pixmap.writable_addr(),
                               pixmap.rowBytes());
}

}  // namespace flutter
