// 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.

// This file contains the implementations of any class in the wrapper that
// - is not fully inline, and
// - is necessary for all clients of the wrapper (either app or plugin).
// It exists instead of the usual structure of having some_class_name.cc files
// so that changes to the set of things that need non-header implementations
// are not breaking changes for the template.
//
// If https://github.com/flutter/flutter/issues/57146 is fixed, this can be
// removed in favor of the normal structure since templates will no longer
// manually include files.

#include <cassert>
#include <iostream>
#include <variant>

#include "binary_messenger_impl.h"
#include "include/flutter/engine_method_result.h"
#include "texture_registrar_impl.h"

namespace flutter {

// ========== binary_messenger_impl.h ==========

namespace {

using FlutterDesktopMessengerScopedLock =
    std::unique_ptr<FlutterDesktopMessenger,
                    decltype(&FlutterDesktopMessengerUnlock)>;

// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
// with a BinaryReply that will send a response on |message|'s response handle.
//
// This serves as an adaptor between the function-pointer-based message callback
// interface provided by the C API and the std::function-based message handler
// interface of BinaryMessenger.
void ForwardToHandler(FlutterDesktopMessengerRef messenger,
                      const FlutterDesktopMessage* message,
                      void* user_data) {
  auto* response_handle = message->response_handle;
  auto messenger_ptr = std::shared_ptr<FlutterDesktopMessenger>(
      FlutterDesktopMessengerAddRef(messenger),
      &FlutterDesktopMessengerRelease);
  BinaryReply reply_handler = [messenger_ptr, response_handle](
                                  const uint8_t* reply,
                                  size_t reply_size) mutable {
    // Note: This lambda can be called on any thread.
    auto lock = FlutterDesktopMessengerScopedLock(
        FlutterDesktopMessengerLock(messenger_ptr.get()),
        &FlutterDesktopMessengerUnlock);
    if (!FlutterDesktopMessengerIsAvailable(messenger_ptr.get())) {
      // Drop reply if it comes in after the engine is destroyed.
      return;
    }
    if (!response_handle) {
      std::cerr << "Error: Response can be set only once. Ignoring "
                   "duplicate response."
                << std::endl;
      return;
    }
    FlutterDesktopMessengerSendResponse(messenger_ptr.get(), response_handle,
                                        reply, reply_size);
    // The engine frees the response handle once
    // FlutterDesktopSendMessageResponse is called.
    response_handle = nullptr;
  };

  const BinaryMessageHandler& message_handler =
      *static_cast<BinaryMessageHandler*>(user_data);

  message_handler(message->message, message->message_size,
                  std::move(reply_handler));
}
}  // namespace

BinaryMessengerImpl::BinaryMessengerImpl(
    FlutterDesktopMessengerRef core_messenger)
    : messenger_(core_messenger) {}

BinaryMessengerImpl::~BinaryMessengerImpl() = default;

void BinaryMessengerImpl::Send(const std::string& channel,
                               const uint8_t* message,
                               size_t message_size,
                               BinaryReply reply) const {
  if (reply == nullptr) {
    FlutterDesktopMessengerSend(messenger_, channel.c_str(), message,
                                message_size);
    return;
  }
  struct Captures {
    BinaryReply reply;
  };
  auto captures = new Captures();
  captures->reply = reply;

  auto message_reply = [](const uint8_t* data, size_t data_size,
                          void* user_data) {
    auto captures = reinterpret_cast<Captures*>(user_data);
    captures->reply(data, data_size);
    delete captures;
  };
  bool result = FlutterDesktopMessengerSendWithReply(
      messenger_, channel.c_str(), message, message_size, message_reply,
      captures);
  if (!result) {
    delete captures;
  }
}

void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
                                            BinaryMessageHandler handler) {
  if (!handler) {
    handlers_.erase(channel);
    FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
                                       nullptr);
    return;
  }
  // Save the handler, to keep it alive.
  handlers_[channel] = std::move(handler);
  BinaryMessageHandler* message_handler = &handlers_[channel];
  // Set an adaptor callback that will invoke the handler.
  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(),
                                     ForwardToHandler, message_handler);
}

// ========== engine_method_result.h ==========

namespace internal {

ReplyManager::ReplyManager(BinaryReply reply_handler)
    : reply_handler_(std::move(reply_handler)) {
  assert(reply_handler_);
}

ReplyManager::~ReplyManager() {
  if (reply_handler_) {
    // Warn, rather than send a not-implemented response, since the engine may
    // no longer be valid at this point.
    std::cerr
        << "Warning: Failed to respond to a message. This is a memory leak."
        << std::endl;
  }
}

void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
  if (!reply_handler_) {
    std::cerr
        << "Error: Only one of Success, Error, or NotImplemented can be "
           "called,"
        << " and it can be called exactly once. Ignoring duplicate result."
        << std::endl;
    return;
  }

  const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
  size_t message_size = data ? data->size() : 0;
  reply_handler_(message, message_size);
  reply_handler_ = nullptr;
}

}  // namespace internal

// ========== texture_registrar_impl.h ==========

TextureRegistrarImpl::TextureRegistrarImpl(
    FlutterDesktopTextureRegistrarRef texture_registrar_ref)
    : texture_registrar_ref_(texture_registrar_ref) {}

TextureRegistrarImpl::~TextureRegistrarImpl() = default;

int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) {
  FlutterDesktopTextureInfo info = {};
  if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
    info.type = kFlutterDesktopPixelBufferTexture;
    info.pixel_buffer_config.user_data = pixel_buffer_texture;
    info.pixel_buffer_config.callback =
        [](size_t width, size_t height,
           void* user_data) -> const FlutterDesktopPixelBuffer* {
      auto texture = static_cast<PixelBufferTexture*>(user_data);
      return texture->CopyPixelBuffer(width, height);
    };
  } else if (auto gpu_surface_texture =
                 std::get_if<GpuSurfaceTexture>(texture)) {
    info.type = kFlutterDesktopGpuSurfaceTexture;
    info.gpu_surface_config.struct_size =
        sizeof(FlutterDesktopGpuSurfaceTextureConfig);
    info.gpu_surface_config.type = gpu_surface_texture->surface_type();
    info.gpu_surface_config.user_data = gpu_surface_texture;
    info.gpu_surface_config.callback =
        [](size_t width, size_t height,
           void* user_data) -> const FlutterDesktopGpuSurfaceDescriptor* {
      auto texture = static_cast<GpuSurfaceTexture*>(user_data);
      return texture->ObtainDescriptor(width, height);
    };
  } else {
    std::cerr << "Attempting to register unknown texture variant." << std::endl;
    return -1;
  }

  int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
      texture_registrar_ref_, &info);
  return texture_id;
}  // namespace flutter

bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) {
  return FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(
      texture_registrar_ref_, texture_id);
}

void TextureRegistrarImpl::UnregisterTexture(int64_t texture_id,
                                             std::function<void()> callback) {
  if (callback == nullptr) {
    FlutterDesktopTextureRegistrarUnregisterExternalTexture(
        texture_registrar_ref_, texture_id, nullptr, nullptr);
    return;
  }

  struct Captures {
    std::function<void()> callback;
  };
  auto captures = new Captures();
  captures->callback = std::move(callback);
  FlutterDesktopTextureRegistrarUnregisterExternalTexture(
      texture_registrar_ref_, texture_id,
      [](void* opaque) {
        auto captures = reinterpret_cast<Captures*>(opaque);
        captures->callback();
        delete captures;
      },
      captures);
}

bool TextureRegistrarImpl::UnregisterTexture(int64_t texture_id) {
  UnregisterTexture(texture_id, nullptr);
  return true;
}

}  // namespace flutter
