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

#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_METHOD_CHANNEL_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_METHOD_CHANNEL_H_

#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
#endif

#include <gio/gio.h>
#include <glib-object.h>

#include "fl_binary_messenger.h"
#include "fl_method_call.h"
#include "fl_method_codec.h"
#include "fl_method_response.h"

G_BEGIN_DECLS

G_DECLARE_FINAL_TYPE(FlMethodChannel,
                     fl_method_channel,
                     FL,
                     METHOD_CHANNEL,
                     GObject)

/**
 * FlMethodChannel:
 *
 * #FlMethodChannel is an object that allows method calls to and from Dart code.
 *
 * The following example shows how to call and handle methods on a channel.
 * See #FlMethodResponse for how to handle errors in more detail.
 *
 * |[<!-- language="C" -->
 * static FlMethodChannel *channel = NULL;
 *
 * static void method_call_cb (FlMethodChannel* channel,
 *                             FlMethodCall* method_call,
 *                             gpointer user_data) {
 *   g_autoptr(FlMethodResponse) response = NULL;
 *   if (strcmp (fl_method_call_get_name (method_call), "Foo.bar") == 0) {
 *     g_autoptr(GError) bar_error = NULL;
 *     g_autoptr(FlValue) result =
 *         do_bar (fl_method_call_get_args (method_call), &bar_error);
 *     if (result == NULL)
 *       response =
 *         FL_METHOD_RESPONSE (fl_method_error_response_new ("bar error",
 *                                                           bar_error->message));
 *     else
 *       response = FL_METHOD_RESPONSE (fl_method_success_response_new
 * (result)); } else response = FL_METHOD_RESPONSE
 * (fl_method_not_implemented_response_new ());
 *
 *   g_autoptr(GError) error = NULL;
 *   if (!fl_method_call_respond(method_call, response))
 *     g_warning ("Failed to send response: %s", error->message);
 * }
 *
 * static void method_response_cb(GObject *object,
 *                                GAsyncResult *result,
 *                                gpointer user_data) {
 *   g_autoptr(GError) error = NULL;
 *   g_autoptr(FlMethodResponse) response =
 *     fl_method_channel_invoke_method_finish (FL_METHOD_CODEC (object), result,
 *                                             &error);
 *   if (response == NULL) {
 *     g_warning ("Failed to call method: %s", error->message);
 *     return;
 *   }
 *
 *   g_autoptr(FlValue) value =
 *     fl_method_response_get_result (response, &error);
 *   if (response == NULL) {
 *     g_warning ("Method returned error: %s", error->message);
 *     return;
 *   }
 *
 *   use_result (value);
 * }
 *
 * static void call_method () {
 *   g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new ();
 *   channel =
 *     fl_method_channel_new(messenger, "flutter/foo", FL_METHOD_CODEC (codec));
 *   fl_method_channel_set_method_call_handler (channel, method_call_cb, NULL,
 * NULL);
 *
 *   g_autoptr(FlValue) args = fl_value_new_string ("Hello World");
 *   fl_method_channel_invoke_method (channel, "Foo.foo", args,
 *                                    cancellable, method_response_cb, NULL);
 * }
 * ]|
 *
 * #FlMethodChannel matches the MethodChannel class in the Flutter services
 * library.
 */

/**
 * FlMethodChannelMethodCallHandler:
 * @channel: an #FlMethodChannel.
 * @method_call: an #FlMethodCall.
 * @user_data: (closure): data provided when registering this handler.
 *
 * Function called when a method call is received. Respond to the method call
 * with fl_method_call_respond(). If the response is not occurring in this
 * callback take a reference to @method_call and release that once it has been
 * responded to. Failing to respond before the last reference to @method_call is
 * dropped is a programming error.
 */
typedef void (*FlMethodChannelMethodCallHandler)(FlMethodChannel* channel,
                                                 FlMethodCall* method_call,
                                                 gpointer user_data);

/**
 * fl_method_channel_new:
 * @messenger: an #FlBinaryMessenger.
 * @name: a channel name.
 * @codec: the method codec.
 *
 * Creates a new method channel. @codec must match the codec used on the Dart
 * end of the channel.
 *
 * Returns: a new #FlMethodChannel.
 */
FlMethodChannel* fl_method_channel_new(FlBinaryMessenger* messenger,
                                       const gchar* name,
                                       FlMethodCodec* codec);

/**
 * fl_method_channel_set_method_call_handler:
 * @channel: an #FlMethodChannel.
 * @handler: function to call when a method call is received on this channel.
 * @user_data: (closure): user data to pass to @handler.
 * @destroy_notify: (allow-none): a function which gets called to free
 * @user_data, or %NULL.
 *
 * Sets the function called when a method call is received from the Dart side of
 * the channel. See #FlMethodChannelMethodCallHandler for details on how to
 * respond to method calls.
 *
 * The handler is removed if the channel is closed or is replaced by another
 * handler, set @destroy_notify if you want to detect this.
 */
void fl_method_channel_set_method_call_handler(
    FlMethodChannel* channel,
    FlMethodChannelMethodCallHandler handler,
    gpointer user_data,
    GDestroyNotify destroy_notify);

/**
 * fl_method_channel_invoke_method:
 * @channel: an #FlMethodChannel.
 * @method: the method to call.
 * @args: (allow-none): arguments to the method, must match what the
 * #FlMethodCodec supports.
 * @cancellable: (allow-none): a #GCancellable or %NULL.
 * @callback: (scope async): (allow-none): a #GAsyncReadyCallback to call when
 * the request is satisfied or %NULL to ignore the response.
 * @user_data: (closure): user data to pass to @callback.
 *
 * Calls a method on this channel.
 */
void fl_method_channel_invoke_method(FlMethodChannel* channel,
                                     const gchar* method,
                                     FlValue* args,
                                     GCancellable* cancellable,
                                     GAsyncReadyCallback callback,
                                     gpointer user_data);

/**
 * fl_method_channel_invoke_method_finish:
 * @channel: an #FlMethodChannel.
 * @result:  #GAsyncResult.
 * @error: (allow-none): #GError location to store the error occurring, or %NULL
 * to ignore.
 *
 * Completes request started with fl_method_channel_invoke_method().
 *
 * Returns: (transfer full): an #FlMethodResponse or %NULL on error.
 */
FlMethodResponse* fl_method_channel_invoke_method_finish(
    FlMethodChannel* channel,
    GAsyncResult* result,
    GError** error);

G_END_DECLS

#endif  // FLUTTER_SHELL_PLATFORM_LINUX_FL_METHOD_CHANNEL_H_
