// 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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>
#include <wayland-client-protocol.h>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/strings/string_number_conversions.h"
#include "brillo/syslog_logging.h"

constexpr char kBgColorFlag[] = "bgcolor";
constexpr char kWidthFlag[] = "width";
constexpr char kHeightFlag[] = "height";
constexpr char kTitleFlag[] = "title";

struct demo_data {
  uint32_t bgcolor;
  uint32_t width;
  uint32_t height;
  const char* title;
  int scale;
  struct wl_compositor* compositor;
  struct wl_shell* shell;
  struct wl_shm* shm;
  struct wl_surface* surface;
  struct wl_shell_surface* shell_surface;
  struct wl_buffer* buffer;
  struct wl_callback* callback;
  struct wl_callback_listener* callback_listener;
  struct wl_output* output;
  struct wl_output_listener* output_listener;
  struct wl_keyboard_listener* keyboard_listener;
  void* shm_ptr;
  bool done;
};

void keyboard_keymap(void* data,
                     struct wl_keyboard* keyboard,
                     uint32_t format,
                     int32_t fd,
                     uint32_t size) {}

void keyboard_enter(void* data,
                    struct wl_keyboard* keyboard,
                    uint32_t serial,
                    struct wl_surface* surface,
                    struct wl_array* keys) {}

void keyboard_leave(void* data,
                    struct wl_keyboard* keyboard,
                    uint32_t serial,
                    struct wl_surface* surface) {}

void keyboard_key(void* data,
                  struct wl_keyboard* keyboard,
                  uint32_t serial,
                  uint32_t time,
                  uint32_t key,
                  uint32_t state) {
  struct demo_data* data_ptr = reinterpret_cast<struct demo_data*>(data);
  // Key pressed.
  if (state == 1) {
    LOG(INFO) << "wayland_demo application detected keypress";
    data_ptr->done = true;
  }
}

void keyboard_modifiers(void* data,
                        struct wl_keyboard* keyboard,
                        uint32_t serial,
                        uint32_t mods_depressed,
                        uint32_t mods_latched,
                        uint32_t mods_locked,
                        uint32_t group) {}

void keyboard_repeat_info(void* data,
                          struct wl_keyboard* keyboard,
                          int32_t rate,
                          int32_t delay) {}

void demo_registry_listener(void* data,
                            struct wl_registry* registry,
                            uint32_t id,
                            const char* interface,
                            uint32_t version) {
  struct demo_data* data_ptr = reinterpret_cast<struct demo_data*>(data);
  if (!strcmp("wl_compositor", interface)) {
    data_ptr->compositor = reinterpret_cast<struct wl_compositor*>(
        wl_registry_bind(registry, id, &wl_compositor_interface, version));
  } else if (!strcmp("wl_shell", interface)) {
    data_ptr->shell = reinterpret_cast<struct wl_shell*>(
        wl_registry_bind(registry, id, &wl_shell_interface, version));
  } else if (!strcmp("wl_shm", interface)) {
    data_ptr->shm = reinterpret_cast<struct wl_shm*>(
        wl_registry_bind(registry, id, &wl_shm_interface, version));
  } else if (!strcmp("wl_output", interface)) {
    data_ptr->output = reinterpret_cast<struct wl_output*>(
        wl_registry_bind(registry, id, &wl_output_interface, version));
    wl_output_add_listener(data_ptr->output, data_ptr->output_listener,
                           data_ptr);
  } else if (!strcmp("wl_seat", interface)) {
    struct wl_seat* seat = reinterpret_cast<struct wl_seat*>(
        wl_registry_bind(registry, id, &wl_seat_interface, version));
    wl_keyboard_add_listener(wl_seat_get_keyboard(seat),
                             data_ptr->keyboard_listener, data_ptr);
  }
}

void demo_registry_remover(void* data,
                           struct wl_registry* registry,
                           uint32_t id) {}

void shell_surface_ping(void* data,
                        struct wl_shell_surface* shell_surface,
                        uint32_t serial) {
  wl_shell_surface_pong(shell_surface, serial);
}

void shell_surface_configure(void* data,
                             struct wl_shell_surface* shell_surface,
                             uint32_t edges,
                             int32_t width,
                             int32_t height) {}

void shell_surface_popup_done(void* data,
                              struct wl_shell_surface* shell_surface) {}

void demo_draw(void* data, struct wl_callback* callback, uint32_t time) {
  struct demo_data* data_ptr = reinterpret_cast<struct demo_data*>(data);
  wl_callback_destroy(data_ptr->callback);
  wl_surface_damage(data_ptr->surface, 0, 0, data_ptr->width, data_ptr->height);
  uint32_t* surface_data = reinterpret_cast<uint32_t*>(data_ptr->shm_ptr);
  for (int i = 0; i < data_ptr->width * data_ptr->height; ++i) {
    surface_data[i] = data_ptr->bgcolor;
  }
  data_ptr->callback = wl_surface_frame(data_ptr->surface);
  wl_surface_attach(data_ptr->surface, data_ptr->buffer, 0, 0);
  wl_callback_add_listener(data_ptr->callback, data_ptr->callback_listener,
                           data_ptr);
  wl_surface_commit(data_ptr->surface);
}

void output_geometry(void* data,
                     struct wl_output* output,
                     int32_t x,
                     int32_t y,
                     int32_t physical_width,
                     int32_t physical_height,
                     int32_t subpixel,
                     const char* make,
                     const char* model,
                     int32_t transform) {}

void output_mode(void* data,
                 struct wl_output* output,
                 uint32_t flags,
                 int32_t width,
                 int32_t height,
                 int32_t refresh) {
  struct demo_data* data_ptr = reinterpret_cast<struct demo_data*>(data);
  if (data_ptr->width == 0) {
    data_ptr->width = width;
    if (data_ptr->scale != 0) {
      data_ptr->width /= data_ptr->scale;
    }
  }
  if (data_ptr->height == 0) {
    data_ptr->height = height;
    if (data_ptr->scale != 0) {
      data_ptr->height /= data_ptr->scale;
    }
  }
}

void output_done(void* data, struct wl_output* output) {}

void output_scale(void* data, struct wl_output* output, int32_t factor) {
  struct demo_data* data_ptr = reinterpret_cast<struct demo_data*>(data);
  data_ptr->scale = factor;
  if (data_ptr->width != 0) {
    data_ptr->width /= factor;
  }
  if (data_ptr->height != 0) {
    data_ptr->height /= factor;
  }
}

int main(int argc, char* argv[]) {
  brillo::InitLog(brillo::kLogToSyslog);
  LOG(INFO) << "Starting wayland_demo application";

  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  struct demo_data data;
  memset(&data, 0, sizeof(data));
  data.done = false;

  data.bgcolor = 0x3388DD;
  if (cl->HasSwitch(kBgColorFlag)) {
    data.bgcolor =
        strtoul(cl->GetSwitchValueASCII(kBgColorFlag).c_str(), nullptr, 0);
  }
  if (cl->HasSwitch(kWidthFlag)) {
    if (!base::StringToUint(cl->GetSwitchValueASCII(kWidthFlag), &data.width)) {
      LOG(ERROR) << "Invalid width parameter passed";
      return -1;
    }
  }
  if (cl->HasSwitch(kHeightFlag)) {
    if (!base::StringToUint(cl->GetSwitchValueASCII(kHeightFlag),
                            &data.height)) {
      LOG(ERROR) << "Invalid height parameter passed";
      return -1;
    }
  }
  data.title = "wayland_demo";
  if (cl->HasSwitch(kTitleFlag)) {
    data.title = cl->GetSwitchValueASCII(kTitleFlag).c_str();
  }

  struct wl_display* display = wl_display_connect(nullptr);
  if (!display) {
    LOG(ERROR) << "Failed connecting to display";
    return -1;
  }

  struct wl_output_listener output_listener = {output_geometry, output_mode,
                                               output_done, output_scale};
  data.output_listener = &output_listener;
  struct wl_registry_listener registry_listener = {
      demo_registry_listener, demo_registry_remover,
  };
  struct wl_keyboard_listener keyboard_listener = {
      keyboard_keymap, keyboard_enter,     keyboard_leave,
      keyboard_key,    keyboard_modifiers, keyboard_repeat_info};
  data.keyboard_listener = &keyboard_listener;

  struct wl_registry* registry = wl_display_get_registry(display);
  wl_registry_add_listener(registry, &registry_listener, &data);

  wl_display_dispatch(display);
  wl_display_roundtrip(display);

  if (!data.compositor) {
    LOG(ERROR) << "Failed to find compositor";
    return -1;
  }
  if (!data.output) {
    LOG(ERROR) << "Failed to get output";
    return -1;
  }

  // Do another roundtrip to ensure we get the wl_output callbacks.
  wl_display_roundtrip(display);

  data.surface = wl_compositor_create_surface(data.compositor);
  if (!data.surface) {
    LOG(ERROR) << "Failed creating surface";
    return -1;
  }
  if (!data.shell) {
    LOG(ERROR) << "Failed getting shell";
    return -1;
  }

  data.shell_surface = wl_shell_get_shell_surface(data.shell, data.surface);
  if (!data.shell_surface) {
    LOG(ERROR) << "Failed getting shell surface";
    return -1;
  }
  const struct wl_shell_surface_listener shell_surface_listener = {
      shell_surface_ping, shell_surface_configure, shell_surface_popup_done};
  wl_shell_surface_add_listener(data.shell_surface, &shell_surface_listener,
                                nullptr);

  wl_shell_surface_set_toplevel(data.shell_surface);
  wl_shell_surface_set_class(data.shell_surface, "wayland_demo");
  wl_shell_surface_set_title(data.shell_surface, data.title);
  data.callback = wl_surface_frame(data.surface);
  struct wl_callback_listener callback_listener = {demo_draw};
  data.callback_listener = &callback_listener;
  wl_callback_add_listener(data.callback, data.callback_listener, &data);

  if (!data.shm) {
    LOG(ERROR) << "Failed getting shared memory";
    return -1;
  }

  size_t stride = data.width * 4 /* 32bpp */;
  size_t shm_size = stride * data.height;
  base::SharedMemory shared_mem;
  shared_mem.CreateAndMapAnonymous(shm_size);
  data.shm_ptr = shared_mem.memory();

  struct wl_shm_pool* pool =
      wl_shm_create_pool(data.shm, shared_mem.handle().fd, shm_size);
  data.buffer = wl_shm_pool_create_buffer(pool, 0, data.width, data.height,
                                          stride, WL_SHM_FORMAT_XRGB8888);
  wl_shm_pool_destroy(pool);

  wl_surface_attach(data.surface, data.buffer, 0, 0);
  wl_surface_commit(data.surface);

  demo_draw(&data, nullptr, 0);
  LOG(INFO) << "wayland_demo application displaying, waiting for keypress";
  do {
  } while (wl_display_dispatch(display) != -1 && !data.done);

  wl_display_disconnect(display);
  LOG(INFO) << "wayland_demo application exiting";
  return 0;
}
