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

#include "device/gamepad/gamepad_device_mac.h"

#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>

#include "base/apple/bridging.h"
#include "base/apple/foundation_util.h"
#include "base/apple/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
#include "device/gamepad/dualshock4_controller.h"
#include "device/gamepad/gamepad_data_fetcher.h"
#include "device/gamepad/gamepad_id_list.h"
#include "device/gamepad/hid_haptic_gamepad.h"
#include "device/gamepad/hid_writer_mac.h"
#include "device/gamepad/xbox_hid_controller.h"

namespace device {

namespace {
// http://www.usb.org/developers/hidpage
const uint16_t kGenericDesktopUsagePage = 0x01;
const uint16_t kGameControlsUsagePage = 0x05;
const uint16_t kButtonUsagePage = 0x09;
const uint16_t kConsumerUsagePage = 0x0c;

const uint16_t kJoystickUsageNumber = 0x04;
const uint16_t kGameUsageNumber = 0x05;
const uint16_t kMultiAxisUsageNumber = 0x08;
const uint16_t kAxisMinimumUsageNumber = 0x30;
const uint16_t kSystemMainMenuUsageNumber = 0x85;
const uint16_t kPowerUsageNumber = 0x30;
const uint16_t kSearchUsageNumber = 0x0221;
const uint16_t kHomeUsageNumber = 0x0223;
const uint16_t kBackUsageNumber = 0x0224;
const uint16_t kRecordUsageNumber = 0xb2;

const int kRumbleMagnitudeMax = 10000;

struct SpecialUsages {
  const uint16_t usage_page;
  const uint16_t usage;
} kSpecialUsages[] = {
    // Xbox One S pre-FW update reports Xbox button as SystemMainMenu over BT.
    {kGenericDesktopUsagePage, kSystemMainMenuUsageNumber},
    // Power is used for the Guide button on the Nvidia Shield 2015 gamepad.
    {kConsumerUsagePage, kPowerUsageNumber},
    // Search is used for the Guide button on the Nvidia Shield 2017 gamepad.
    {kConsumerUsagePage, kSearchUsageNumber},
    // Start, Back, and Guide buttons are often reported as Consumer Home or
    // Back.
    {kConsumerUsagePage, kHomeUsageNumber},
    {kConsumerUsagePage, kBackUsageNumber},
    {kConsumerUsagePage, kRecordUsageNumber},
};
const size_t kSpecialUsagesLen = std::size(kSpecialUsages);

float NormalizeAxis(CFIndex value, CFIndex min, CFIndex max) {
  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
}

float NormalizeUInt8Axis(uint8_t value, uint8_t min, uint8_t max) {
  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
}

float NormalizeUInt16Axis(uint16_t value, uint16_t min, uint16_t max) {
  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
}

float NormalizeUInt32Axis(uint32_t value, uint32_t min, uint32_t max) {
  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
}

GamepadBusType QueryBusType(IOHIDDeviceRef device) {
  CFStringRef transport_cf = base::apple::CFCast<CFStringRef>(
      IOHIDDeviceGetProperty(device, CFSTR(kIOHIDTransportKey)));
  if (transport_cf) {
    std::string transport = base::SysCFStringRefToUTF8(transport_cf);
    if (transport == kIOHIDTransportUSBValue)
      return GAMEPAD_BUS_USB;
    if (transport == kIOHIDTransportBluetoothValue ||
        transport == kIOHIDTransportBluetoothLowEnergyValue) {
      return GAMEPAD_BUS_BLUETOOTH;
    }
  }
  return GAMEPAD_BUS_UNKNOWN;
}

}  // namespace

GamepadDeviceMac::GamepadDeviceMac(int location_id,
                                   IOHIDDeviceRef device_ref,
                                   std::string_view product_name,
                                   int vendor_id,
                                   int product_id)
    : location_id_(location_id),
      device_ref_(device_ref),
      bus_type_(QueryBusType(device_ref_)),
      ff_device_ref_(nullptr),
      ff_effect_ref_(nullptr) {
  auto gamepad_id =
      GamepadIdList::Get().GetGamepadId(product_name, vendor_id, product_id);

  if (Dualshock4Controller::IsDualshock4(gamepad_id)) {
    dualshock4_ = std::make_unique<Dualshock4Controller>(
        gamepad_id, bus_type_, std::make_unique<HidWriterMac>(device_ref));
    return;
  }

  if (XboxHidController::IsXboxHid(gamepad_id)) {
    xbox_hid_ = std::make_unique<XboxHidController>(
        std::make_unique<HidWriterMac>(device_ref));
    return;
  }

  if (HidHapticGamepad::IsHidHaptic(vendor_id, product_id)) {
    hid_haptics_ = HidHapticGamepad::Create(
        vendor_id, product_id, std::make_unique<HidWriterMac>(device_ref));
    return;
  }

  if (device_ref) {
    ff_device_ref_ = CreateForceFeedbackDevice(device_ref);
    if (ff_device_ref_) {
      ff_effect_ref_ = CreateForceFeedbackEffect(ff_device_ref_, &ff_effect_,
                                                 &ff_custom_force_, force_data_,
                                                 axes_data_, direction_data_);
    }
  }
}

GamepadDeviceMac::~GamepadDeviceMac() = default;

void GamepadDeviceMac::DoShutdown() {
  if (ff_device_ref_) {
    if (ff_effect_ref_) {
      FFDeviceReleaseEffect(ff_device_ref_, ff_effect_ref_);
      ff_effect_ref_ = nullptr;
    }
    FFReleaseDevice(ff_device_ref_);
    ff_device_ref_ = nullptr;
  }
  if (dualshock4_)
    dualshock4_->Shutdown();
  dualshock4_.reset();
  if (xbox_hid_)
    xbox_hid_->Shutdown();
  xbox_hid_.reset();
  if (hid_haptics_)
    hid_haptics_->Shutdown();
  hid_haptics_.reset();
}

// static
bool GamepadDeviceMac::CheckCollection(IOHIDElementRef element) {
  // Check that a parent collection of this element matches one of the usage
  // numbers that we are looking for.
  while ((element = IOHIDElementGetParent(element)) != nullptr) {
    uint32_t usage_page = IOHIDElementGetUsagePage(element);
    uint32_t usage = IOHIDElementGetUsage(element);
    if (usage_page == kGenericDesktopUsagePage) {
      if (usage == kJoystickUsageNumber || usage == kGameUsageNumber ||
          usage == kMultiAxisUsageNumber) {
        return true;
      }
    }
  }
  return false;
}

bool GamepadDeviceMac::AddButtonsAndAxes(Gamepad* gamepad) {
  bool has_buttons = AddButtons(gamepad);
  bool has_axes = AddAxes(gamepad);
  gamepad->timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
  return (has_buttons || has_axes);
}

bool GamepadDeviceMac::AddButtons(Gamepad* gamepad) {
  DCHECK(gamepad);
  memset(gamepad->buttons, 0, sizeof(gamepad->buttons));
  std::fill(button_elements_, button_elements_ + Gamepad::kButtonsLengthCap,
            nullptr);

  base::apple::ScopedCFTypeRef<CFArrayRef> elements(
      IOHIDDeviceCopyMatchingElements(device_ref_, /*matching=*/nullptr,
                                      kIOHIDOptionsTypeNone));
  if (!elements) {
    // IOHIDDeviceCopyMatchingElements returns nullptr if we don't have
    // permission to access the referenced IOHIDDevice.
    return false;
  }

  std::vector<IOHIDElementRef> special_element(kSpecialUsagesLen, nullptr);
  size_t button_count = 0;
  size_t unmapped_button_count = 0;

  for (CFIndex i = 0; i < CFArrayGetCount(elements.get()); ++i) {
    IOHIDElementRef element =
        (IOHIDElementRef)CFArrayGetValueAtIndex(elements.get(), i);
    if (!CheckCollection(element))
      continue;

    uint32_t usage_page = IOHIDElementGetUsagePage(element);
    uint32_t usage = IOHIDElementGetUsage(element);
    if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button) {
      if (usage_page == kButtonUsagePage && usage > 0) {
        size_t button_index = size_t{usage - 1};

        // Ignore buttons with large usage values.
        if (button_index >= Gamepad::kButtonsLengthCap)
          continue;

        // Button index already assigned, ignore.
        if (button_elements_[button_index])
          continue;

        button_elements_[button_index] = element;
        gamepad->buttons[button_index].used = true;
        button_count = std::max(button_count, button_index + 1);
      } else {
        // Check for common gamepad buttons that are not on the Button usage
        // page. Button indices are assigned in a second pass.
        for (size_t special_index = 0; special_index < kSpecialUsagesLen;
             ++special_index) {
          const auto& special = kSpecialUsages[special_index];
          if (usage_page == special.usage_page && usage == special.usage) {
            special_element[special_index] = element;
            ++unmapped_button_count;
          }
        }
      }
    }
  }

  if (unmapped_button_count > 0) {
    // Insert unmapped buttons at unused button indices.
    size_t button_index = 0;
    for (size_t special_index = 0; special_index < kSpecialUsagesLen;
         ++special_index) {
      if (!special_element[special_index])
        continue;

      // Advance to the next unused button index.
      while (button_index < Gamepad::kButtonsLengthCap &&
             button_elements_[button_index]) {
        ++button_index;
      }
      if (button_index >= Gamepad::kButtonsLengthCap)
        break;

      button_elements_[button_index] = special_element[special_index];
      gamepad->buttons[button_index].used = true;
      button_count = std::max(button_count, button_index + 1);

      if (--unmapped_button_count == 0)
        break;
    }
  }

  gamepad->buttons_length = button_count;
  return gamepad->buttons_length > 0;
}

bool GamepadDeviceMac::AddAxes(Gamepad* gamepad) {
  base::apple::ScopedCFTypeRef<CFArrayRef> elements(
      IOHIDDeviceCopyMatchingElements(device_ref_, nullptr,
                                      kIOHIDOptionsTypeNone));
  DCHECK(elements);
  DCHECK(gamepad);
  memset(gamepad->axes, 0, sizeof(gamepad->axes));
  std::fill(axis_elements_, axis_elements_ + Gamepad::kAxesLengthCap, nullptr);
  std::fill(axis_minimums_, axis_minimums_ + Gamepad::kAxesLengthCap, 0);
  std::fill(axis_maximums_, axis_maximums_ + Gamepad::kAxesLengthCap, 0);
  std::fill(axis_report_sizes_, axis_report_sizes_ + Gamepad::kAxesLengthCap,
            0);

  // Most axes are mapped so that their index in the Gamepad axes array
  // corresponds to the usage ID. However, this is not possible when the usage
  // ID would cause the axis index to exceed the bounds of the axes array.
  // Axes with large usage IDs are mapped in a second pass.
  size_t axis_count = 0;
  size_t unmapped_axis_count = 0;

  for (CFIndex i = 0; i < CFArrayGetCount(elements.get()); ++i) {
    IOHIDElementRef element =
        (IOHIDElementRef)CFArrayGetValueAtIndex(elements.get(), i);
    if (!CheckCollection(element))
      continue;

    uint32_t usage_page = IOHIDElementGetUsagePage(element);
    uint32_t usage = IOHIDElementGetUsage(element);
    if (IOHIDElementGetType(element) != kIOHIDElementTypeInput_Misc ||
        usage < kAxisMinimumUsageNumber) {
      continue;
    }

    size_t axis_index = size_t{usage - kAxisMinimumUsageNumber};
    if (axis_index < Gamepad::kAxesLengthCap) {
      // Axis index already assigned, ignore.
      if (axis_elements_[axis_index])
        continue;
      axis_elements_[axis_index] = element;
      axis_count = std::max(axis_count, axis_index + 1);
    } else if (usage_page <= kGameControlsUsagePage) {
      // Assign an index for this axis in the second pass.
      ++unmapped_axis_count;
    }
  }

  if (unmapped_axis_count > 0) {
    // Insert unmapped axes at unused axis indices.
    size_t axis_index = 0;
    for (CFIndex i = 0; i < CFArrayGetCount(elements.get()); ++i) {
      IOHIDElementRef element =
          (IOHIDElementRef)CFArrayGetValueAtIndex(elements.get(), i);
      if (!CheckCollection(element))
        continue;

      uint32_t usage_page = IOHIDElementGetUsagePage(element);
      uint32_t usage = IOHIDElementGetUsage(element);
      if (IOHIDElementGetType(element) != kIOHIDElementTypeInput_Misc ||
          usage < kAxisMinimumUsageNumber ||
          usage_page > kGameControlsUsagePage) {
        continue;
      }

      // Ignore axes with small usage IDs that should have been mapped in the
      // initial pass.
      if (size_t{usage - kAxisMinimumUsageNumber} < Gamepad::kAxesLengthCap)
        continue;

      // Advance to the next unused axis index.
      while (axis_index < Gamepad::kAxesLengthCap &&
             axis_elements_[axis_index]) {
        ++axis_index;
      }
      if (axis_index >= Gamepad::kAxesLengthCap)
        break;

      axis_elements_[axis_index] = element;
      axis_count = std::max(axis_count, axis_index + 1);

      if (--unmapped_axis_count == 0)
        break;
    }
  }

  // Fetch the logical range and report size for each axis.
  for (size_t axis_index = 0; axis_index < axis_count; ++axis_index) {
    IOHIDElementRef element = axis_elements_[axis_index];
    if (element != nullptr) {
      CFIndex axis_min = IOHIDElementGetLogicalMin(element);
      CFIndex axis_max = IOHIDElementGetLogicalMax(element);

      // Some HID axes report a logical range of -1 to 0 signed, which must be
      // interpreted as 0 to -1 unsigned for correct normalization behavior.
      if (axis_min == -1 && axis_max == 0) {
        axis_max = -1;
        axis_min = 0;
      }

      axis_minimums_[axis_index] = axis_min;
      axis_maximums_[axis_index] = axis_max;
      axis_report_sizes_[axis_index] = IOHIDElementGetReportSize(element);

      gamepad->axes_used |= 1 << axis_index;
    }
  }

  gamepad->axes_length = axis_count;
  return gamepad->axes_length > 0;
}

void GamepadDeviceMac::UpdateGamepadForValue(IOHIDValueRef value,
                                             Gamepad* gamepad) {
  DCHECK(gamepad);
  IOHIDElementRef element = IOHIDValueGetElement(value);
  uint32_t value_length = IOHIDValueGetLength(value);

  if (dualshock4_) {
    // Handle Dualshock4 input reports that do not specify HID gamepad usages
    // in the report descriptor.
    uint32_t report_id = IOHIDElementGetReportID(element);
    auto report = base::make_span(IOHIDValueGetBytePtr(value), value_length);
    if (dualshock4_->ProcessInputReport(report_id, report, gamepad))
      return;
  }

  // Values larger than 4 bytes cannot be handled by IOHIDValueGetIntegerValue.
  if (value_length > 4)
    return;

  // Find and fill in the associated button event, if any.
  for (size_t i = 0; i < gamepad->buttons_length; ++i) {
    if (button_elements_[i] == element) {
      bool pressed = IOHIDValueGetIntegerValue(value);
      gamepad->buttons[i].pressed = pressed;
      gamepad->buttons[i].value = pressed ? 1.f : 0.f;
      gamepad->timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
      return;
    }
  }

  // Find and fill in the associated axis event, if any.
  for (size_t i = 0; i < gamepad->axes_length; ++i) {
    if (axis_elements_[i] == element) {
      CFIndex axis_min = axis_minimums_[i];
      CFIndex axis_max = axis_maximums_[i];
      CFIndex axis_value = IOHIDValueGetIntegerValue(value);

      if (axis_min > axis_max) {
        // We'll need to interpret this axis as unsigned during normalization.
        switch (axis_report_sizes_[i]) {
          case 8:
            gamepad->axes[i] =
                NormalizeUInt8Axis(axis_value, axis_min, axis_max);
            break;
          case 16:
            gamepad->axes[i] =
                NormalizeUInt16Axis(axis_value, axis_min, axis_max);
            break;
          case 32:
            gamepad->axes[i] =
                NormalizeUInt32Axis(axis_value, axis_min, axis_max);
            break;
        }
      } else {
        gamepad->axes[i] = NormalizeAxis(axis_value, axis_min, axis_max);
      }
      gamepad->timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
      return;
    }
  }
}

bool GamepadDeviceMac::SupportsVibration() {
  return dualshock4_ || xbox_hid_ || hid_haptics_ || ff_device_ref_;
}

void GamepadDeviceMac::SetVibration(mojom::GamepadEffectParametersPtr params) {
  if (dualshock4_) {
    dualshock4_->SetVibration(std::move(params));
    return;
  }

  if (xbox_hid_) {
    xbox_hid_->SetVibration(std::move(params));
    return;
  }

  if (hid_haptics_) {
    hid_haptics_->SetVibration(std::move(params));
    return;
  }

  if (ff_device_ref_) {
    FFCUSTOMFORCE* ff_custom_force =
        static_cast<FFCUSTOMFORCE*>(ff_effect_.lpvTypeSpecificParams);
    DCHECK(ff_custom_force);
    DCHECK(ff_custom_force->rglForceData);

    ff_custom_force->rglForceData[0] =
        static_cast<LONG>(params->strong_magnitude * kRumbleMagnitudeMax);
    ff_custom_force->rglForceData[1] =
        static_cast<LONG>(params->weak_magnitude * kRumbleMagnitudeMax);

    // Download the effect to the device and start the effect.
    HRESULT res = FFEffectSetParameters(
        ff_effect_ref_, &ff_effect_,
        FFEP_DURATION | FFEP_STARTDELAY | FFEP_TYPESPECIFICPARAMS);
    if (res == FF_OK)
      FFEffectStart(ff_effect_ref_, 1, FFES_SOLO);
  }
}

void GamepadDeviceMac::SetZeroVibration() {
  if (dualshock4_) {
    dualshock4_->SetZeroVibration();
    return;
  }

  if (xbox_hid_) {
    xbox_hid_->SetZeroVibration();
    return;
  }

  if (hid_haptics_) {
    hid_haptics_->SetZeroVibration();
    return;
  }

  if (ff_effect_ref_)
    FFEffectStop(ff_effect_ref_);
}

// static
FFDeviceObjectReference GamepadDeviceMac::CreateForceFeedbackDevice(
    IOHIDDeviceRef device_ref) {
  io_service_t service = IOHIDDeviceGetService(device_ref);

  if (service == MACH_PORT_NULL)
    return nullptr;

  HRESULT res = FFIsForceFeedback(service);
  if (res != FF_OK)
    return nullptr;

  FFDeviceObjectReference ff_device_ref;
  res = FFCreateDevice(service, &ff_device_ref);
  if (res != FF_OK)
    return nullptr;

  return ff_device_ref;
}

// static
FFEffectObjectReference GamepadDeviceMac::CreateForceFeedbackEffect(
    FFDeviceObjectReference ff_device_ref,
    FFEFFECT* ff_effect,
    FFCUSTOMFORCE* ff_custom_force,
    LONG* force_data,
    DWORD* axes_data,
    LONG* direction_data) {
  DCHECK(ff_effect);
  DCHECK(ff_custom_force);
  DCHECK(force_data);
  DCHECK(axes_data);
  DCHECK(direction_data);

  FFCAPABILITIES caps;
  HRESULT res = FFDeviceGetForceFeedbackCapabilities(ff_device_ref, &caps);
  if (res != FF_OK)
    return nullptr;

  if ((caps.supportedEffects & FFCAP_ET_CUSTOMFORCE) == 0)
    return nullptr;

  force_data[0] = 0;
  force_data[1] = 0;
  axes_data[0] = caps.ffAxes[0];
  axes_data[1] = caps.ffAxes[1];
  direction_data[0] = 0;
  direction_data[1] = 0;
  ff_custom_force->cChannels = 2;
  ff_custom_force->cSamples = 2;
  ff_custom_force->rglForceData = force_data;
  ff_custom_force->dwSamplePeriod = 100000;  // 100 ms
  ff_effect->dwSize = sizeof(FFEFFECT);
  ff_effect->dwFlags = FFEFF_OBJECTOFFSETS | FFEFF_SPHERICAL;
  ff_effect->dwDuration = 5000000;     // 5 seconds
  ff_effect->dwSamplePeriod = 100000;  // 100 ms
  ff_effect->dwGain = 10000;
  ff_effect->dwTriggerButton = FFEB_NOTRIGGER;
  ff_effect->dwTriggerRepeatInterval = 0;
  ff_effect->cAxes = caps.numFfAxes;
  ff_effect->rgdwAxes = axes_data;
  ff_effect->rglDirection = direction_data;
  ff_effect->lpEnvelope = nullptr;
  ff_effect->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE);
  ff_effect->lpvTypeSpecificParams = ff_custom_force;
  ff_effect->dwStartDelay = 0;

  FFEffectObjectReference ff_effect_ref;
  res = FFDeviceCreateEffect(ff_device_ref, kFFEffectType_CustomForce_ID,
                             ff_effect, &ff_effect_ref);
  if (res != FF_OK)
    return nullptr;

  return ff_effect_ref;
}

base::WeakPtr<AbstractHapticGamepad> GamepadDeviceMac::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

}  // namespace device
