// Copyright 2020 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 <errno.h>
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "gaming-input-unstable-v2-client-protocol.h"  // NOLINT(build/include_directory)

// Overview of state management via gaming events, in order:
// 1) Acquire gaming seats (in sommelier.cc)
// 2) Add listeners to gaming seats
// 3) Listen for zcr_gaming_seat_v2.gamepad_added to construct a 'default'
//    game controller (not currently implemented)
//    Calls libevdev_new, libevdev_enable_event_type,
//          libevdev_uinput_create_from_device
// 4) Listen for zcr_gaming_seat_v2.gamepad_added_with_device_info to construct
//    a custom game controller
//    Calls libevdev_new
// 5) Listen for zcr_gamepad_v2.axis_added to fill in a custom game controller
//    Calls libevdev_enable_event_type
// 6) Listen for zcr_gamepad_v2.activated to finalize a custom game controller
//    Calls libevdev_uinput_create_from_device
// 7) Listen for zcr_gamepad_v2.axis to set frame state for game controller
//    Calls libevdev_uinput_write_event
// 8) Listen for zcr_gamepad_v2.button to set frame state for game controller
//    Calls libevdev_uinput_write_event
// 9) Listen for zcr_gamepad_v2.frame to emit collected frame
//    Calls libevdev_uinput_write_event(EV_SYN)
// 10) Listen for zcr_gamepad_v2.removed to destroy gamepad
//    Must handle gamepads in all states of construction or error

enum GamepadActivationState {
  kStateUnknown = 0,    // Should not happen
  kStatePending = 1,    // Constructed, pending axis definition
  kStateActivated = 2,  // Fully activated
  kStateError = 3       // Error occurred during construction; ignore gracefully
};

const char kXboxName[] = "Microsoft X-Box One S pad";
const uint32_t kUsbBus = 0x03;
const uint32_t kXboxVendor = 0x45e;
const uint32_t kXboxProduct = 0x2ea;
const uint32_t kXboxVersion = 0x301;

const uint32_t kStadiaVendor = 0x18d1;
const uint32_t kStadiaProduct = 0x9400;
const uint32_t kStadiaVersion = 0x111;

// Note: the majority of protocol errors are treated as non-fatal, and
// are intended to be handled gracefully, as is removal at any
// state of construction or operation. We should expect that
// 'sudden removal' can happen at any time, due to hotplugging
// or unexpected state changes from the wayland server.

static void sl_internal_gamepad_removed(void* data,
                                        struct zcr_gamepad_v2* gamepad) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_removed");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;

  assert(host_gamepad->state == kStatePending ||
         host_gamepad->state == kStateActivated ||
         host_gamepad->state == kStateError);

  if (host_gamepad->uinput_dev != NULL)
    libevdev_uinput_destroy(host_gamepad->uinput_dev);
  if (host_gamepad->ev_dev != NULL)
    libevdev_free(host_gamepad->ev_dev);

  zcr_gamepad_v2_destroy(gamepad);

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

static uint32_t remap_axis(struct sl_host_gamepad* host_gamepad,
                           uint32_t axis) {
  if (host_gamepad->stadia) {
    if (axis == ABS_Z)
      axis = ABS_RX;
    else if (axis == ABS_RZ)
      axis = ABS_RY;
    else if (axis == ABS_BRAKE)
      axis = ABS_Z;
    else if (axis == ABS_GAS)
      axis = ABS_RZ;
  }
  return axis;
}

static void sl_internal_gamepad_axis(void* data,
                                     struct zcr_gamepad_v2* gamepad,
                                     uint32_t time,
                                     uint32_t axis,
                                     wl_fixed_t value) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_axis");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;

  if (host_gamepad->state != kStateActivated)
    return;

  axis = remap_axis(host_gamepad, axis);

  // Note: incoming time is ignored, it will be regenerated from current time.
  libevdev_uinput_write_event(host_gamepad->uinput_dev, EV_ABS, axis,
                              wl_fixed_to_double(value));
}

static void sl_internal_gamepad_button(void* data,
                                       struct zcr_gamepad_v2* gamepad,
                                       uint32_t time,
                                       uint32_t button,
                                       uint32_t state,
                                       wl_fixed_t analog) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_button");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;

  if (host_gamepad->state != kStateActivated)
    return;

  // Note: Exo wayland server always sends analog==0, only pay attention
  // to state.
  int value = (state == ZCR_GAMEPAD_V2_BUTTON_STATE_PRESSED) ? 1 : 0;

  // Note: incoming time is ignored, it will be regenerated from current time.
  libevdev_uinput_write_event(host_gamepad->uinput_dev, EV_KEY, button, value);
}

static void sl_internal_gamepad_frame(void* data,
                                      struct zcr_gamepad_v2* gamepad,
                                      uint32_t time) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_frame");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;

  if (host_gamepad->state != kStateActivated)
    return;

  // Note: incoming time is ignored, it will be regenerated from current time.
  libevdev_uinput_write_event(host_gamepad->uinput_dev, EV_SYN, SYN_REPORT, 0);
}

static void sl_internal_gamepad_axis_added(void* data,
                                           struct zcr_gamepad_v2* gamepad,
                                           uint32_t index,
                                           int32_t min_value,
                                           int32_t max_value,
                                           int32_t flat,
                                           int32_t fuzz,
                                           int32_t resolution) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_axis_added");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;
  struct input_absinfo info = {.value = 0,  // Does this matter?
                               .minimum = min_value,
                               .maximum = max_value,
                               .fuzz = fuzz,
                               .flat = flat,
                               .resolution = resolution};

  if (host_gamepad->state != kStatePending) {
    fprintf(stderr, "error: %s invoked in unexpected state %d\n", __func__,
            host_gamepad->state);
    host_gamepad->state = kStateError;
    return;
  }

  index = remap_axis(host_gamepad, index);

  libevdev_enable_event_code(host_gamepad->ev_dev, EV_ABS, index, &info);
}

static void sl_internal_gamepad_activated(void* data,
                                          struct zcr_gamepad_v2* gamepad) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_activated");
  struct sl_host_gamepad* host_gamepad = (struct sl_host_gamepad*)data;

  if (host_gamepad->state != kStatePending) {
    fprintf(stderr, "error: %s invoked in unexpected state %d\n", __func__,
            host_gamepad->state);
    host_gamepad->state = kStateError;
    return;
  }

  int err = libevdev_uinput_create_from_device(host_gamepad->ev_dev,
                                               LIBEVDEV_UINPUT_OPEN_MANAGED,
                                               &host_gamepad->uinput_dev);
  if (err == 0) {
    // TODO(kenalba): can we destroy and clean up the ev_dev now?
    host_gamepad->state = kStateActivated;
  } else {
    fprintf(stderr,
            "error: libevdev_uinput_create_from_device failed with error %d\n",
            err);
    host_gamepad->state = kStateError;
  }
}

static void sl_internal_gamepad_vibrator_added(
    void* data,
    struct zcr_gamepad_v2* gamepad,
    struct zcr_gamepad_vibrator_v2* vibrator) {
  TRACE_EVENT("gaming", "sl_internal_gamepad_vibrator_added");
  // TODO(kenalba): add vibration logic
}

static const struct zcr_gamepad_v2_listener sl_internal_gamepad_listener = {
    sl_internal_gamepad_removed,       sl_internal_gamepad_axis,
    sl_internal_gamepad_button,        sl_internal_gamepad_frame,
    sl_internal_gamepad_axis_added,    sl_internal_gamepad_activated,
    sl_internal_gamepad_vibrator_added};

static void sl_internal_gaming_seat_gamepad_added_with_device_info(
    void* data,
    struct zcr_gaming_seat_v2* gaming_seat,
    struct zcr_gamepad_v2* gamepad,
    const char* name,
    uint32_t bus,
    uint32_t vendor_id,
    uint32_t product_id,
    uint32_t version) {
  TRACE_EVENT("gaming",
              "sl_internal_gaming_seat_gamepad_added_with_device_info");
  struct sl_context* ctx = (struct sl_context*)data;
  struct sl_host_gamepad* host_gamepad =
      static_cast<sl_host_gamepad*>(malloc(sizeof(struct sl_host_gamepad)));
  assert(host_gamepad);
  wl_list_insert(&ctx->gamepads, &host_gamepad->link);
  zcr_gamepad_v2_set_user_data(gamepad, host_gamepad);
  zcr_gamepad_v2_add_listener(gamepad, &sl_internal_gamepad_listener,
                              host_gamepad);

  host_gamepad->ctx = ctx;
  host_gamepad->state = kStatePending;
  host_gamepad->ev_dev = libevdev_new();
  host_gamepad->uinput_dev = NULL;
  host_gamepad->stadia = false;

  if (host_gamepad->ev_dev == NULL) {
    fprintf(stderr, "error: libevdev_new failed\n");
    host_gamepad->state = kStateError;
    return;
  }

  // We provide limited remapping at this time. Only moderately XBox360
  // HID compatible controllers are likely to work well.

  if (product_id == kStadiaProduct && vendor_id == kStadiaVendor &&
      version == kStadiaVersion) {
    host_gamepad->stadia = true;
  }

  // Describe a common controller
  libevdev_set_name(host_gamepad->ev_dev, kXboxName);
  libevdev_set_id_bustype(host_gamepad->ev_dev, kUsbBus);
  libevdev_set_id_vendor(host_gamepad->ev_dev, kXboxVendor);
  libevdev_set_id_product(host_gamepad->ev_dev, kXboxProduct);
  libevdev_set_id_version(host_gamepad->ev_dev, kXboxVersion);

  // Enable common set of buttons

  // Note: Do not enable BTN_TL2 or BTN_TR2, as they will significantly
  // change the Linux joydev interpretation of the triggers on ABS_Z/ABS_RZ.
  int buttons[] = {BTN_SOUTH,  BTN_EAST,  BTN_NORTH,  BTN_WEST,
                   BTN_TL,     BTN_TR,    BTN_THUMBL, BTN_THUMBR,
                   BTN_SELECT, BTN_START, BTN_MODE};

  for (unsigned int i = 0; i < ARRAY_SIZE(buttons); i++)
    libevdev_enable_event_code(host_gamepad->ev_dev, EV_KEY, buttons[i], NULL);
}  // NOLINT(whitespace/indent), lint bug b/173143790

// Note: not currently implemented by Exo.
static void sl_internal_gaming_seat_gamepad_added(
    void* data,
    struct zcr_gaming_seat_v2* gaming_seat,
    struct zcr_gamepad_v2* gamepad) {
  TRACE_EVENT("gaming", "sl_internal_gaming_seat_gamepad_added");
  fprintf(stderr,
          "error: sl_internal_gaming_seat_gamepad_added unimplemented\n");
}

static const struct zcr_gaming_seat_v2_listener
    sl_internal_gaming_seat_listener = {
        sl_internal_gaming_seat_gamepad_added,
        sl_internal_gaming_seat_gamepad_added_with_device_info};

void sl_gaming_seat_add_listener(struct sl_context* ctx) {
  if (ctx->gaming_input_manager && ctx->gaming_input_manager->internal) {
    TRACE_EVENT("gaming", "sl_gaming_seat_add_listener");
    // TODO(kenalba): does gaming_seat need to persist in ctx?
    struct zcr_gaming_seat_v2* gaming_seat =
        zcr_gaming_input_v2_get_gaming_seat(ctx->gaming_input_manager->internal,
                                            ctx->default_seat->proxy);
    zcr_gaming_seat_v2_add_listener(gaming_seat,
                                    &sl_internal_gaming_seat_listener, ctx);
  }
}
