#!/usr/bin/python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Code generator DeviceCapabilities literal."""

import argparse
import ctypes
import evdev
import os
import sys


TEST_DATA_GROUP_SIZE = 64  # Aligns with sysfs on 64-bit devices.


def bits_to_groups(bits):
  return (bits + TEST_DATA_GROUP_SIZE - 1) / TEST_DATA_GROUP_SIZE


# As in /sys/class/input/input*/capabilities/*
def serialize_bitfield(bitfield, max_bit):
  result = ""
  group_count = bits_to_groups(max_bit)
  for group in xrange(group_count - 1, -1, -1):
    group_val = 0
    for group_bit in xrange(TEST_DATA_GROUP_SIZE):
      code = group * TEST_DATA_GROUP_SIZE + group_bit
      if code in bitfield:
        group_val |= (1 << group_bit)
    if group_val or result:
      result += '%x' % group_val
      if group:
        result += ' '
  if not result:
    return '0'
  return result


def dump_absinfo(out, capabilities, identifier):
  out.write('const DeviceAbsoluteAxis %s[] = {\n' % identifier)

  for code, absinfo in capabilities[evdev.ecodes.EV_ABS]:
    # Set value := 0 to make it deterministic.
    code_name = evdev.ecodes.bytype[evdev.ecodes.EV_ABS][code]
    absinfo_struct = (0, absinfo.min, absinfo.max, absinfo.fuzz, absinfo.flat,
                      absinfo.resolution)
    data = (code_name,) + absinfo_struct
    out.write('    {%s, {%d, %d, %d, %d, %d, %d}},\n' % data)

  out.write('};\n')


def dump_capabilities(out, dev, identifier):
  capabilities = dev.capabilities()
  has_abs = evdev.ecodes.EV_ABS in capabilities

  sysfs_path = '/sys/class/input/' + os.path.basename(dev.fn)

  # python-evdev is missing some features
  uniq = open(sysfs_path + '/device/uniq', 'r').read().strip()
  prop = open(sysfs_path + '/device/properties', 'r').read().strip()
  ff = open(sysfs_path + '/device/capabilities/ff', 'r').read().strip()

  # python-evdev parses the id wrong.
  bustype = open(sysfs_path + '/device/id/bustype', 'r').read().strip()
  vendor = open(sysfs_path + '/device/id/vendor', 'r').read().strip()
  product = open(sysfs_path + '/device/id/product', 'r').read().strip()
  version = open(sysfs_path + '/device/id/version', 'r').read().strip()

  # python-evdev drops EV_REP from the event set.
  ev = open(sysfs_path + '/device/capabilities/ev', 'r').read().strip()

  if ctypes.sizeof(ctypes.c_long()) != 8:
    # /sys/class/input/*/properties format is word size dependent.
    # Could be fixed by regrouping but for now, just raise an error.
    raise ValueError("Must be run on 64-bit machine")

  key_bits = capabilities.get(evdev.ecodes.EV_KEY, [])
  rel_bits = capabilities.get(evdev.ecodes.EV_REL, [])
  abs_bits = [abs[0] for abs in capabilities.get(evdev.ecodes.EV_ABS, [])]
  msc_bits = capabilities.get(evdev.ecodes.EV_MSC, [])
  sw_bits = capabilities.get(evdev.ecodes.EV_SW, [])
  led_bits = capabilities.get(evdev.ecodes.EV_LED, [])

  fields = [
    ('path', os.path.realpath(sysfs_path)),
    ('name', dev.name),
    ('phys', dev.phys),
    ('uniq', uniq),
    ('bustype', bustype),
    ('vendor', vendor),
    ('product', product),
    ('version', version),
    ('prop', prop),
    ('ev', ev),
    ('key', serialize_bitfield(key_bits, evdev.ecodes.KEY_CNT)),
    ('rel', serialize_bitfield(rel_bits, evdev.ecodes.REL_CNT)),
    ('abs', serialize_bitfield(abs_bits, evdev.ecodes.ABS_CNT)),
    ('msc', serialize_bitfield(msc_bits, evdev.ecodes.MSC_CNT)),
    ('sw', serialize_bitfield(sw_bits, evdev.ecodes.SW_CNT)),
    ('led', serialize_bitfield(led_bits, evdev.ecodes.LED_CNT)),
    ('ff', ff),
  ]

  if has_abs:
    absinfo_identifier = identifier + 'AbsAxes'
    dump_absinfo(out, capabilities, absinfo_identifier)

  out.write('const DeviceCapabilities %s = {\n' % identifier)
  for name, val in fields:
    out.write('    /* %s */ "%s",\n' % (name, val))

  if has_abs:
    out.write('    %s,\n' % absinfo_identifier)
    out.write('    arraysize(%s),\n' % absinfo_identifier)

  out.write('};\n')


def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument('device')
  parser.add_argument('identifier')
  args = parser.parse_args(argv)

  dev = evdev.InputDevice(args.device)
  out = sys.stdout

  dump_capabilities(out, dev, args.identifier)
  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
