// 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);
 *
 *   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.
 *
 * Sets the function called when a method is called. Call
 * fl_method_call_respond() when the method completes.
 */
void fl_method_channel_set_method_call_handler(
    FlMethodChannel* channel,
    FlMethodChannelMethodCallHandler handler,
    gpointer user_data);

/**
 * 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_
