// 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;
  std::string 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);
  }

  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, data.title.c_str());
  wl_shell_surface_set_title(data.shell_surface, data.title.c_str());
  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().GetHandle(), 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;
}
