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

// Included first as it collides with the X11 headers.
#include "gtest/gtest.h"

#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_event_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
#include "flutter/shell/platform/linux/testing/mock_renderer.h"

// Data passed in tests.
typedef struct {
  GMainLoop* loop;
  int count;
} TestData;

// Creates a mock engine that responds to platform messages.
static FlEngine* make_mock_engine() {
  g_autoptr(FlDartProject) project = fl_dart_project_new();
  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
  g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
  g_autoptr(GError) engine_error = nullptr;
  EXPECT_TRUE(fl_engine_start(engine, &engine_error));
  EXPECT_EQ(engine_error, nullptr);

  return static_cast<FlEngine*>(g_object_ref(engine));
}

// Triggers the engine to start listening to the channel.
static void listen_channel(FlBinaryMessenger* messenger, FlValue* args) {
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(FlMethodChannel) channel = fl_method_channel_new(
      messenger, "test/standard-method", FL_METHOD_CODEC(codec));

  // Trigger the engine to make a method call.
  g_autoptr(FlValue) invoke_args = fl_value_new_list();
  fl_value_append_take(invoke_args, fl_value_new_string("test/standard-event"));
  fl_value_append_take(invoke_args, fl_value_new_string("listen"));
  g_autoptr(FlValue) value =
      args != nullptr ? fl_value_ref(args) : fl_value_new_null();
  fl_value_append(invoke_args, value);
  fl_method_channel_invoke_method(channel, "InvokeMethod", invoke_args, nullptr,
                                  nullptr, nullptr);
}

// Triggers the engine to cancel the subscription to the channel.
static void cancel_channel(FlBinaryMessenger* messenger, FlValue* args) {
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(FlMethodChannel) channel = fl_method_channel_new(
      messenger, "test/standard-method", FL_METHOD_CODEC(codec));

  // Trigger the engine to make a method call.
  g_autoptr(FlValue) invoke_args = fl_value_new_list();
  fl_value_append_take(invoke_args, fl_value_new_string("test/standard-event"));
  fl_value_append_take(invoke_args, fl_value_new_string("cancel"));
  g_autoptr(FlValue) value =
      args != nullptr ? fl_value_ref(args) : fl_value_new_null();
  fl_value_append(invoke_args, value);
  fl_method_channel_invoke_method(channel, "InvokeMethod", invoke_args, nullptr,
                                  nullptr, nullptr);
}

// Called when the remote end starts listening on the channel.
static FlMethodErrorResponse* listen_listen_cb(FlEventChannel* channel,
                                               FlValue* args,
                                               gpointer user_data) {
  EXPECT_EQ(fl_value_get_type(args), FL_VALUE_TYPE_NULL);

  g_main_loop_quit(static_cast<GMainLoop*>(user_data));

  return nullptr;
}

// Checks we detect a listen event.
TEST(FlEventChannelTest, Listen) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(channel, listen_listen_cb, nullptr, loop,
                                       nullptr);

  listen_channel(messenger, nullptr);

  // Blocks here until listen_listen_cb called.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}

// Called when the remote end starts listening on the channel.
static FlMethodErrorResponse* listen_exception_listen_cb(
    FlEventChannel* channel,
    FlValue* args,
    gpointer user_data) {
  return fl_method_error_response_new("LISTEN-ERROR", "LISTEN-ERROR-MESSAGE",
                                      nullptr);
}

// Called when a the test engine notifies us what response we sent in the
// ListenException test.
static void listen_exception_response_cb(
    FlBinaryMessenger* messenger,
    const gchar* channel,
    GBytes* message,
    FlBinaryMessengerResponseHandle* response_handle,
    gpointer user_data) {
  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
                                    nullptr);

  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(GError) error = nullptr;
  g_autoptr(FlMethodResponse) response =
      fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
  EXPECT_NE(response, nullptr);
  EXPECT_EQ(error, nullptr);

  EXPECT_TRUE(FL_IS_METHOD_ERROR_RESPONSE(response));
  EXPECT_STREQ(
      fl_method_error_response_get_code(FL_METHOD_ERROR_RESPONSE(response)),
      "LISTEN-ERROR");
  EXPECT_STREQ(
      fl_method_error_response_get_message(FL_METHOD_ERROR_RESPONSE(response)),
      "LISTEN-ERROR-MESSAGE");

  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
}

// Checks we can generate a listen exception.
TEST(FlEventChannelTest, ListenException) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(channel, listen_exception_listen_cb,
                                       nullptr, loop, nullptr);

  // Listen for response to the engine.
  fl_binary_messenger_set_message_handler_on_channel(
      messenger, "test/responses", listen_exception_response_cb, loop, nullptr);

  listen_channel(messenger, nullptr);

  // Blocks here until listen_exception_response_cb called.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}

// Called when the remote end cancels their subscription.
static FlMethodErrorResponse* cancel_cancel_cb(FlEventChannel* channel,
                                               FlValue* args,
                                               gpointer user_data) {
  EXPECT_EQ(fl_value_get_type(args), FL_VALUE_TYPE_NULL);

  g_main_loop_quit(static_cast<GMainLoop*>(user_data));

  return nullptr;
}

// Checks we detect a cancel event.
TEST(FlEventChannelTest, Cancel) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(channel, nullptr, cancel_cancel_cb, loop,
                                       nullptr);

  listen_channel(messenger, nullptr);
  cancel_channel(messenger, nullptr);

  // Blocks here until cancel_cancel_cb called.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}

// Called when the remote end cancels their subscription.
static FlMethodErrorResponse* cancel_exception_cancel_cb(
    FlEventChannel* channel,
    FlValue* args,
    gpointer user_data) {
  return fl_method_error_response_new("CANCEL-ERROR", "CANCEL-ERROR-MESSAGE",
                                      nullptr);
}

// Called when a the test engine notifies us what response we sent in the
// CancelException test.
static void cancel_exception_response_cb(
    FlBinaryMessenger* messenger,
    const gchar* channel,
    GBytes* message,
    FlBinaryMessengerResponseHandle* response_handle,
    gpointer user_data) {
  TestData* data = static_cast<TestData*>(user_data);

  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
                                    nullptr);

  data->count++;
  if (data->count == 2) {
    g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
    g_autoptr(GError) error = nullptr;
    g_autoptr(FlMethodResponse) response = fl_method_codec_decode_response(
        FL_METHOD_CODEC(codec), message, &error);
    EXPECT_NE(response, nullptr);
    EXPECT_EQ(error, nullptr);

    EXPECT_TRUE(FL_IS_METHOD_ERROR_RESPONSE(response));
    EXPECT_STREQ(
        fl_method_error_response_get_code(FL_METHOD_ERROR_RESPONSE(response)),
        "CANCEL-ERROR");
    EXPECT_STREQ(fl_method_error_response_get_message(
                     FL_METHOD_ERROR_RESPONSE(response)),
                 "CANCEL-ERROR-MESSAGE");

    g_main_loop_quit(data->loop);
  }
}

// Checks we can generate a cancel exception.
TEST(FlEventChannelTest, CancelException) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
  TestData data;
  data.loop = loop;
  data.count = 0;

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(
      channel, nullptr, cancel_exception_cancel_cb, &data, nullptr);

  // Listen for response to the engine.
  fl_binary_messenger_set_message_handler_on_channel(
      messenger, "test/responses", cancel_exception_response_cb, &data,
      nullptr);

  listen_channel(messenger, nullptr);
  cancel_channel(messenger, nullptr);

  // Blocks here until cancel_exception_response_cb called.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}

// Called when the remote end starts listening on the channel.
static FlMethodErrorResponse* args_listen_cb(FlEventChannel* channel,
                                             FlValue* args,
                                             gpointer user_data) {
  g_autoptr(FlValue) expected_args = fl_value_new_string("LISTEN-ARGS");
  EXPECT_TRUE(fl_value_equal(args, expected_args));

  return nullptr;
}

// Called when the remote end cancels their subscription.
static FlMethodErrorResponse* args_cancel_cb(FlEventChannel* channel,
                                             FlValue* args,
                                             gpointer user_data) {
  g_autoptr(FlValue) expected_args = fl_value_new_string("CANCEL-ARGS");
  EXPECT_TRUE(fl_value_equal(args, expected_args));

  g_main_loop_quit(static_cast<GMainLoop*>(user_data));

  return nullptr;
}

// Checks args are passed to listen/cancel.
TEST(FlEventChannelTest, Args) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(channel, args_listen_cb, args_cancel_cb,
                                       loop, nullptr);

  g_autoptr(FlValue) listen_args = fl_value_new_string("LISTEN-ARGS");
  listen_channel(messenger, listen_args);
  g_autoptr(FlValue) cancel_args = fl_value_new_string("CANCEL-ARGS");
  cancel_channel(messenger, cancel_args);

  // Blocks here until args_cancel_cb called.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}

// Called when the remote end starts listening on the channel.
static FlMethodErrorResponse* send_events_listen_cb(FlEventChannel* channel,
                                                    FlValue* args,
                                                    gpointer user_data) {
  // Send some events.
  for (int i = 0; i < 5; i++) {
    g_autoptr(FlValue) event = fl_value_new_int(i);
    g_autoptr(GError) error = nullptr;
    EXPECT_TRUE(fl_event_channel_send(channel, event, nullptr, &error));
    EXPECT_EQ(error, nullptr);
  }

  return nullptr;
}

// Called when a the test engine notifies us what event we sent in the
// Test test.
static void send_events_events_cb(
    FlBinaryMessenger* messenger,
    const gchar* channel,
    GBytes* message,
    FlBinaryMessengerResponseHandle* response_handle,
    gpointer user_data) {
  TestData* data = static_cast<TestData*>(user_data);

  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(GError) error = nullptr;
  g_autoptr(FlMethodResponse) response =
      fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
  EXPECT_NE(response, nullptr);
  EXPECT_EQ(error, nullptr);

  FlValue* result = fl_method_response_get_result(response, &error);
  EXPECT_NE(result, nullptr);
  EXPECT_EQ(error, nullptr);

  EXPECT_EQ(fl_value_get_type(result), FL_VALUE_TYPE_INT);
  EXPECT_EQ(fl_value_get_int(result), data->count);
  data->count++;

  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
                                    nullptr);

  // Got all the results!
  if (data->count == 5) {
    g_main_loop_quit(data->loop);
  }
}

// Checks can send events.
TEST(FlEventChannelTest, Test) {
  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
  TestData data;
  data.loop = loop;
  data.count = 0;

  g_autoptr(FlEngine) engine = make_mock_engine();
  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  FlEventChannel* channel = fl_event_channel_new(
      messenger, "test/standard-event", FL_METHOD_CODEC(codec));
  fl_event_channel_set_stream_handlers(channel, send_events_listen_cb, nullptr,
                                       &data, nullptr);

  // Listen for events from the engine.
  fl_binary_messenger_set_message_handler_on_channel(
      messenger, "test/events", send_events_events_cb, &data, nullptr);

  listen_channel(messenger, nullptr);
  cancel_channel(messenger, nullptr);

  // Blocks here until send_events_events_cb receives the last event.
  g_main_loop_run(loop);

  // Manually unref because the compiler complains 'channel' is unused.
  g_object_unref(channel);
}
