// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sommelier.h"  // NOLINT(build/include_directory)
#include "sommelier-tracing.h"  // NOLINT(build/include_directory)

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>

static void sl_registry_bind(struct wl_client* client,
                             struct wl_resource* resource,
                             uint32_t name,
                             const char* interface,
                             uint32_t version,
                             uint32_t id) {
  TRACE_EVENT("display", "sl_registry_bind");
  struct sl_host_registry* host =
      static_cast<sl_host_registry*>(wl_resource_get_user_data(resource));
  struct sl_global* global;

  wl_list_for_each(global, &host->ctx->globals, link) {
    if (global->name == name)
      break;
  }

  assert(&global->link != &host->ctx->globals);
  assert(version != 0);
  assert(global->version >= version);

  global->bind(client, global->data, version, id);
}

static const struct wl_registry_interface sl_registry_implementation = {
    sl_registry_bind};

static void sl_sync_callback_done(void* data,
                                  struct wl_callback* callback,
                                  uint32_t serial) {
  TRACE_EVENT("display", "sl_sync_callback_done");
  struct sl_host_callback* host =
      static_cast<sl_host_callback*>(wl_callback_get_user_data(callback));

  wl_callback_send_done(host->resource, serial);
  wl_resource_destroy(host->resource);
}

static const struct wl_callback_listener sl_sync_callback_listener = {
    sl_sync_callback_done};

static void sl_host_callback_destroy(struct wl_resource* resource) {
  struct sl_host_callback* host =
      static_cast<sl_host_callback*>(wl_resource_get_user_data(resource));

  wl_callback_destroy(host->proxy);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_display_sync(struct wl_client* client,
                            struct wl_resource* resource,
                            uint32_t id) {
  struct sl_context* ctx =
      static_cast<sl_context*>(wl_resource_get_user_data(resource));
  struct sl_host_callback* host_callback =
      static_cast<sl_host_callback*>(malloc(sizeof(*host_callback)));
  assert(host_callback);

  host_callback->resource =
      wl_resource_create(client, &wl_callback_interface, 1, id);
  wl_resource_set_implementation(host_callback->resource, NULL, host_callback,
                                 sl_host_callback_destroy);
  host_callback->proxy = wl_display_sync(ctx->display);
  wl_callback_set_user_data(host_callback->proxy, host_callback);
  wl_callback_add_listener(host_callback->proxy, &sl_sync_callback_listener,
                           host_callback);
}

static void sl_destroy_host_registry(struct wl_resource* resource) {
  struct sl_host_registry* host =
      static_cast<sl_host_registry*>(wl_resource_get_user_data(resource));

  wl_list_remove(&host->link);
  free(host);
}

static void sl_display_get_registry(struct wl_client* client,
                                    struct wl_resource* resource,
                                    uint32_t id) {
  struct sl_context* ctx =
      static_cast<sl_context*>(wl_resource_get_user_data(resource));
  struct sl_global* global;

  struct sl_host_registry* host_registry =
      static_cast<sl_host_registry*>(malloc(sizeof(*host_registry)));
  assert(host_registry);

  host_registry->ctx = ctx;
  host_registry->resource =
      wl_resource_create(client, &wl_registry_interface, 1, id);
  wl_list_insert(&ctx->registries, &host_registry->link);
  wl_resource_set_implementation(host_registry->resource,
                                 &sl_registry_implementation, host_registry,
                                 sl_destroy_host_registry);

  wl_list_for_each(global, &ctx->globals, link) {
    wl_resource_post_event(host_registry->resource, WL_REGISTRY_GLOBAL,
                           global->name, global->interface->name,
                           global->version);
  }
}

static const struct wl_display_interface sl_display_implementation = {
    sl_display_sync, sl_display_get_registry};

static enum wl_iterator_result sl_set_implementation(
    struct wl_resource* resource, void* user_data) {
  struct sl_context* ctx = (struct sl_context*)user_data;

  if (strcmp(wl_resource_get_class(resource), "wl_display") == 0) {
    wl_resource_set_implementation(resource, &sl_display_implementation, ctx,
                                   NULL);
    return WL_ITERATOR_STOP;
  }

  return WL_ITERATOR_CONTINUE;
}

void sl_set_display_implementation(struct sl_context* ctx) {
  // Find display resource and set implementation.
  wl_client_for_each_resource(ctx->client, sl_set_implementation, ctx);
}
