// 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 is a historical legacy, predating the proc table API. It has been
// updated to continue to work with the proc table, but new tests should not
// rely on replacements set up here, but instead use test-local replacements
// for any functions relevant to that test.
//
// Over time existing tests should be migrated and this file should be removed.

#include <cstring>

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_response.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
#include "gtest/gtest.h"

const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1;

struct _FlutterEngine {
  bool running;
  FlutterPlatformMessageCallback platform_message_callback;
  FlutterTaskRunnerPostTaskCallback platform_post_task_callback;
  void* user_data;

  _FlutterEngine(FlutterPlatformMessageCallback platform_message_callback,
                 FlutterTaskRunnerPostTaskCallback platform_post_task_callback,
                 void* user_data)
      : running(false),
        platform_message_callback(platform_message_callback),
        platform_post_task_callback(platform_post_task_callback),
        user_data(user_data) {}
};

struct _FlutterPlatformMessageResponseHandle {
  FlutterDataCallback data_callback;
  void* user_data;
  std::string channel;
  bool released;

  // Constructor for a response handle generated by the engine.
  explicit _FlutterPlatformMessageResponseHandle(std::string channel)
      : data_callback(nullptr),
        user_data(nullptr),
        channel(channel),
        released(false) {}

  // Constructor for a response handle generated by the shell.
  _FlutterPlatformMessageResponseHandle(FlutterDataCallback data_callback,
                                        void* user_data)
      : data_callback(data_callback), user_data(user_data), released(false) {}
};

struct _FlutterTaskRunner {
  uint64_t task;
  std::string channel;
  const FlutterPlatformMessageResponseHandle* response_handle;
  uint8_t* message;
  size_t message_size;

  _FlutterTaskRunner(
      uint64_t task,
      const std::string& channel,
      const FlutterPlatformMessageResponseHandle* response_handle,
      const uint8_t* message,
      size_t message_size)
      : task(task),
        channel(channel),
        response_handle(response_handle),
        message_size(message_size) {
    if (message_size > 0) {
      this->message = static_cast<uint8_t*>(malloc(message_size));
      memcpy(this->message, message, message_size);
    } else {
      this->message = nullptr;
    }
  }
  ~_FlutterTaskRunner() {
    if (response_handle != nullptr) {
      EXPECT_TRUE(response_handle->released);
      delete response_handle;
    }
    free(message);
  }
};

namespace {

// Send a response from the engine.
static void send_response(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const std::string& channel,
    const FlutterPlatformMessageResponseHandle* response_handle,
    const uint8_t* message,
    size_t message_size) {
  if (response_handle == nullptr) {
    return;
  }

  FlutterTask task;
  task.runner = new _FlutterTaskRunner(1234, channel, response_handle, message,
                                       message_size);
  task.task = task.runner->task;
  engine->platform_post_task_callback(task, 0, engine->user_data);
}

// Send a message from the engine.
static void send_message(FLUTTER_API_SYMBOL(FlutterEngine) engine,
                         const std::string& channel,
                         const uint8_t* message,
                         size_t message_size) {
  FlutterTask task;
  task.runner =
      new _FlutterTaskRunner(1234, channel, nullptr, message, message_size);
  task.task = task.runner->task;
  engine->platform_post_task_callback(task, 0, engine->user_data);
}

static void invoke_method(FLUTTER_API_SYMBOL(FlutterEngine) engine,
                          const std::string& channel,
                          const gchar* name,
                          FlValue* args) {
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(GError) error = nullptr;
  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
      FL_METHOD_CODEC(codec), name, args, &error);
  EXPECT_NE(message, nullptr);
  EXPECT_EQ(error, nullptr);

  FlutterTask task;
  task.runner = new _FlutterTaskRunner(
      1234, channel, nullptr,
      static_cast<const uint8_t*>(g_bytes_get_data(message, nullptr)),
      g_bytes_get_size(message));
  task.task = task.runner->task;
  engine->platform_post_task_callback(task, 0, engine->user_data);
}

FlutterEngineResult FlutterEngineCreateAOTData(
    const FlutterEngineAOTDataSource* source,
    FlutterEngineAOTData* data_out) {
  *data_out = nullptr;
  return kSuccess;
}

FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data) {
  return kSuccess;
}

FlutterEngineResult FlutterEngineInitialize(size_t version,
                                            const FlutterRendererConfig* config,
                                            const FlutterProjectArgs* args,
                                            void* user_data,
                                            FLUTTER_API_SYMBOL(FlutterEngine) *
                                                engine_out) {
  EXPECT_NE(config, nullptr);

  EXPECT_NE(args, nullptr);
  EXPECT_NE(args->platform_message_callback, nullptr);
  EXPECT_NE(args->custom_task_runners, nullptr);
  EXPECT_NE(args->custom_task_runners->platform_task_runner, nullptr);
  EXPECT_NE(args->custom_task_runners->platform_task_runner->post_task_callback,
            nullptr);

  EXPECT_NE(user_data, nullptr);

  EXPECT_EQ(config->type, kOpenGL);

  *engine_out = new _FlutterEngine(
      args->platform_message_callback,
      args->custom_task_runners->platform_task_runner->post_task_callback,
      user_data);
  return kSuccess;
}

FlutterEngineResult FlutterEngineRunInitialized(
    FLUTTER_API_SYMBOL(FlutterEngine) engine) {
  engine->running = true;
  return kSuccess;
}

FlutterEngineResult FlutterEngineRun(size_t version,
                                     const FlutterRendererConfig* config,
                                     const FlutterProjectArgs* args,
                                     void* user_data,
                                     FLUTTER_API_SYMBOL(FlutterEngine) *
                                         engine_out) {
  EXPECT_NE(config, nullptr);
  EXPECT_NE(args, nullptr);
  EXPECT_NE(user_data, nullptr);
  EXPECT_NE(engine_out, nullptr);

  FlutterEngineResult result =
      FlutterEngineInitialize(version, config, args, user_data, engine_out);
  if (result != kSuccess) {
    return result;
  }
  return FlutterEngineRunInitialized(*engine_out);
}

FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine)
                                              engine) {
  delete engine;
  return kSuccess;
}

FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine)
                                                  engine) {
  return kSuccess;
}

FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterWindowMetricsEvent* event) {
  EXPECT_TRUE(engine->running);
  return kSuccess;
}

FlutterEngineResult FlutterEngineSendPointerEvent(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPointerEvent* events,
    size_t events_count) {
  return kSuccess;
}

FlutterEngineResult FlutterEngineSendKeyEvent(FLUTTER_API_SYMBOL(FlutterEngine)
                                                  engine,
                                              const FlutterKeyEvent* event,
                                              FlutterKeyEventCallback callback,
                                              void* user_data) {
  return kSuccess;
}

FLUTTER_EXPORT
FlutterEngineResult FlutterEngineSendPlatformMessage(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPlatformMessage* message) {
  EXPECT_TRUE(engine->running);

  if (strcmp(message->channel, "test/echo") == 0) {
    // Responds with the same message received.
    send_response(engine, message->channel, message->response_handle,
                  message->message, message->message_size);
  } else if (strcmp(message->channel, "test/send-message") == 0) {
    // Triggers the engine to send a message.
    send_response(engine, message->channel, message->response_handle, nullptr,
                  0);
    send_message(engine, "test/messages", message->message,
                 message->message_size);
  } else if (strcmp(message->channel, "test/standard-method") == 0) {
    g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
    g_autoptr(GBytes) m = g_bytes_new(message->message, message->message_size);
    g_autofree gchar* name = nullptr;
    g_autoptr(FlValue) args = nullptr;
    g_autoptr(GError) error = nullptr;
    EXPECT_TRUE(fl_method_codec_decode_method_call(FL_METHOD_CODEC(codec), m,
                                                   &name, &args, &error));
    EXPECT_EQ(error, nullptr);

    g_autoptr(GBytes) response = nullptr;
    if (strcmp(name, "Echo") == 0) {
      // Returns args as a success result.
      response = fl_method_codec_encode_success_envelope(FL_METHOD_CODEC(codec),
                                                         args, &error);
      EXPECT_EQ(error, nullptr);
    } else if (strcmp(name, "Error") == 0) {
      // Returns an error result.
      const gchar* code = nullptr;
      const gchar* message = nullptr;
      FlValue* details = nullptr;
      if (fl_value_get_length(args) >= 2) {
        FlValue* code_value = fl_value_get_list_value(args, 0);
        EXPECT_EQ(fl_value_get_type(code_value), FL_VALUE_TYPE_STRING);
        code = fl_value_get_string(code_value);
        FlValue* message_value = fl_value_get_list_value(args, 1);
        message = fl_value_get_type(message_value) == FL_VALUE_TYPE_STRING
                      ? fl_value_get_string(message_value)
                      : nullptr;
      }
      if (fl_value_get_length(args) >= 3) {
        details = fl_value_get_list_value(args, 2);
      }
      response = fl_method_codec_encode_error_envelope(
          FL_METHOD_CODEC(codec), code, message, details, &error);
      EXPECT_EQ(error, nullptr);
    } else if (strcmp(name, "InvokeMethod") == 0) {
      // Gets the engine to call the shell.
      if (fl_value_get_length(args) == 3) {
        FlValue* channel_value = fl_value_get_list_value(args, 0);
        EXPECT_EQ(fl_value_get_type(channel_value), FL_VALUE_TYPE_STRING);
        const gchar* channel = fl_value_get_string(channel_value);
        FlValue* name_value = fl_value_get_list_value(args, 1);
        EXPECT_EQ(fl_value_get_type(name_value), FL_VALUE_TYPE_STRING);
        const gchar* name = fl_value_get_string(name_value);
        FlValue* method_args = fl_value_get_list_value(args, 2);
        invoke_method(engine, channel, name, method_args);
      }
      response = fl_method_codec_encode_success_envelope(FL_METHOD_CODEC(codec),
                                                         nullptr, &error);
      EXPECT_EQ(error, nullptr);
    } else {
      // Returns "not implemented".
      response = g_bytes_new(nullptr, 0);
    }

    send_response(
        engine, message->channel, message->response_handle,
        static_cast<const uint8_t*>(g_bytes_get_data(response, nullptr)),
        g_bytes_get_size(response));
  } else if (strcmp(message->channel, "test/nullptr-response") == 0) {
    // Sends a null response.
    send_response(engine, message->channel, message->response_handle, nullptr,
                  0);
  } else if (strcmp(message->channel, "test/standard-event") == 0) {
    // Send a message so the shell can check the events sent.
    send_message(engine, "test/events", message->message,
                 message->message_size);
  } else if (strcmp(message->channel, "test/failure") == 0) {
    // Generates an internal error.
    return kInternalInconsistency;
  } else if (strcmp(message->channel, "test/key-event-handled") == 0 ||
             strcmp(message->channel, "test/key-event-not-handled") == 0) {
    bool value = strcmp(message->channel, "test/key-event-handled") == 0;
    g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
    g_autoptr(FlValue) handledValue = fl_value_new_map();
    fl_value_set_string_take(handledValue, "handled", fl_value_new_bool(value));
    g_autoptr(GBytes) response = fl_message_codec_encode_message(
        FL_MESSAGE_CODEC(codec), handledValue, nullptr);
    send_response(
        engine, message->channel, message->response_handle,
        static_cast<const uint8_t*>(g_bytes_get_data(response, nullptr)),
        g_bytes_get_size(response));
  } else if (strcmp(message->channel, "test/key-event-delayed") == 0) {
    static std::unique_ptr<const FlutterPlatformMessageResponseHandle>
        delayed_response_handle = nullptr;
    g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
    g_autoptr(FlValue) handledValue = fl_value_new_map();
    fl_value_set_string_take(handledValue, "handled", fl_value_new_bool(true));
    g_autoptr(GBytes) response = fl_message_codec_encode_message(
        FL_MESSAGE_CODEC(codec), handledValue, nullptr);
    if (delayed_response_handle == nullptr) {
      delayed_response_handle.reset(message->response_handle);
    } else {
      send_response(
          engine, message->channel, message->response_handle,
          static_cast<const uint8_t*>(g_bytes_get_data(response, nullptr)),
          g_bytes_get_size(response));
      send_response(
          engine, message->channel, delayed_response_handle.release(),
          static_cast<const uint8_t*>(g_bytes_get_data(response, nullptr)),
          g_bytes_get_size(response));
    }
  }

  return kSuccess;
}

FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterDataCallback data_callback,
    void* user_data,
    FlutterPlatformMessageResponseHandle** response_out) {
  EXPECT_TRUE(engine->running);
  EXPECT_NE(data_callback, nullptr);
  EXPECT_NE(user_data, nullptr);

  _FlutterPlatformMessageResponseHandle* handle =
      new _FlutterPlatformMessageResponseHandle(data_callback, user_data);

  *response_out = handle;
  return kSuccess;
}

FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterPlatformMessageResponseHandle* response) {
  EXPECT_NE(engine, nullptr);
  EXPECT_NE(response, nullptr);

  EXPECT_TRUE(engine->running);

  EXPECT_FALSE(response->released);
  response->released = true;

  return kSuccess;
}

FlutterEngineResult FlutterEngineSendPlatformMessageResponse(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    const FlutterPlatformMessageResponseHandle* handle,
    const uint8_t* data,
    size_t data_length) {
  EXPECT_NE(engine, nullptr);
  EXPECT_NE(handle, nullptr);

  EXPECT_TRUE(engine->running);

  // Send a message so the shell can check the responses received.
  if (handle->channel != "test/responses") {
    send_message(engine, "test/responses", data, data_length);
  }

  EXPECT_FALSE(handle->released);

  delete handle;

  return kSuccess;
}

FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine)
                                             engine,
                                         const FlutterTask* task) {
  EXPECT_NE(engine, nullptr);
  EXPECT_NE(task, nullptr);
  EXPECT_NE(task->runner, nullptr);

  FlutterTaskRunner runner = task->runner;
  EXPECT_NE(runner, nullptr);
  const FlutterPlatformMessageResponseHandle* response_handle =
      runner->response_handle;
  if (response_handle != nullptr) {
    EXPECT_NE(response_handle->data_callback, nullptr);
    response_handle->data_callback(runner->message, runner->message_size,
                                   response_handle->user_data);
  } else {
    _FlutterPlatformMessageResponseHandle* handle =
        new _FlutterPlatformMessageResponseHandle(runner->channel);

    FlutterPlatformMessage message;
    message.struct_size = sizeof(FlutterPlatformMessage);
    message.channel = runner->channel.c_str();
    message.message = runner->message;
    message.message_size = runner->message_size;
    message.response_handle = handle;
    engine->platform_message_callback(&message, engine->user_data);
  }

  delete runner;

  return kSuccess;
}

bool FlutterEngineRunsAOTCompiledDartCode() {
  return false;
}

FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine)
                                                   engine,
                                               const FlutterLocale** locales,
                                               size_t locales_count) {
  return kSuccess;
}

FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    bool enabled) {
  return kSuccess;
}

FlutterEngineResult FlutterEngineDispatchSemanticsAction(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    uint64_t id,
    FlutterSemanticsAction action,
    const uint8_t* data,
    size_t data_length) {
  return kSuccess;
}

}  // namespace

FlutterEngineResult FlutterEngineGetProcAddresses(
    FlutterEngineProcTable* table) {
  if (!table) {
    return kInvalidArguments;
  }

  FlutterEngineProcTable empty_table = {};
  *table = empty_table;

  table->CreateAOTData = &FlutterEngineCreateAOTData;
  table->CollectAOTData = &FlutterEngineCollectAOTData;
  table->Run = &FlutterEngineRun;
  table->Shutdown = &FlutterEngineShutdown;
  table->Initialize = &FlutterEngineInitialize;
  table->Deinitialize = &FlutterEngineDeinitialize;
  table->RunInitialized = &FlutterEngineRunInitialized;
  table->SendWindowMetricsEvent = &FlutterEngineSendWindowMetricsEvent;
  table->SendPointerEvent = &FlutterEngineSendPointerEvent;
  table->SendKeyEvent = &FlutterEngineSendKeyEvent;
  table->SendPlatformMessage = &FlutterEngineSendPlatformMessage;
  table->PlatformMessageCreateResponseHandle =
      &FlutterPlatformMessageCreateResponseHandle;
  table->PlatformMessageReleaseResponseHandle =
      &FlutterPlatformMessageReleaseResponseHandle;
  table->SendPlatformMessageResponse =
      &FlutterEngineSendPlatformMessageResponse;
  table->RunTask = &FlutterEngineRunTask;
  table->UpdateLocales = &FlutterEngineUpdateLocales;
  table->UpdateSemanticsEnabled = &FlutterEngineUpdateSemanticsEnabled;
  table->DispatchSemanticsAction = &FlutterEngineDispatchSemanticsAction;
  table->RunsAOTCompiledDartCode = &FlutterEngineRunsAOTCompiledDartCode;

  return kSuccess;
}
