#!/usr/bin/env python2
# Copyright 2017 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.

"""The example code for getting touchpad info for factory with hammerd API."""

from __future__ import print_function

import argparse
import collections
import ctypes
import shlex

import hammerd_api


# The mask of the hardware write protection.
# TODO(akahuang): Move to hammerd_api.py
EC_FLASH_PROTECT_RO_AT_BOOT = (1 << 0)
EC_FLASH_PROTECT_RO_NOW = (1 << 1)
EC_FLASH_PROTECT_ALL_NOW = (1 << 2)
EC_FLASH_PROTECT_GPIO_ASSERTED = (1 << 3)
EC_FLASH_PROTECT_ERROR_STUCK = (1 << 4)
EC_FLASH_PROTECT_ERROR_INCONSISTENT = (1 << 5)
EC_FLASH_PROTECT_ALL_AT_BOOT = (1 << 6)
EC_FLASH_PROTECT_RW_AT_BOOT = (1 << 7)
EC_FLASH_PROTECT_RW_NOW = (1 << 8)
EC_FLASH_PROTECT_ROLLBACK_AT_BOOT = (1 << 9)
EC_FLASH_PROTECT_ROLLBACK_NOW = (1 << 10)

FLASH_PROTECT_ALL = (EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW |
                     EC_FLASH_PROTECT_RW_AT_BOOT | EC_FLASH_PROTECT_RW_NOW |
                     EC_FLASH_PROTECT_ROLLBACK_AT_BOOT |
                     EC_FLASH_PROTECT_ROLLBACK_NOW |
                     EC_FLASH_PROTECT_ALL_AT_BOOT |EC_FLASH_PROTECT_ALL_NOW |
                     EC_FLASH_PROTECT_GPIO_ASSERTED)

def GetHammerdArguments():
  """Parses the hammerd.override and retrieves the arguments.

  The format of the file is:
    env FOO=1234  # comment of FOO
    env BAR="string value"  # comment of BAR

  Returns:
    a dict containing the arguments of hammerd process. The type of the key and
    value are string. e.g.
    {
      'FOO': '1234',
      'BAR': 'string value'
    }
  """
  ARGUMENT_FILE_PATH = '/etc/init/hammerd.override'
  REQUIRED_ARGUMENTS = [
      'EC_IMAGE_PATH',
      'TOUCHPAD_IMAGE_PATH',
      'VENDOR_ID',
      'PRODUCT_ID',
      'USB_PATH']

  ret = {}
  with open(ARGUMENT_FILE_PATH, 'r') as f:
    for line in f:
      tokens = shlex.split(line)
      if len(tokens) >= 2 and tokens[0] == 'env':
        key, _unused_sel, value = tokens[1].partition('=')
        ret[key] = value

  missing_args = set(REQUIRED_ARGUMENTS) - set(ret.keys())
  if missing_args:
    raise ValueError('Missing arguments: %s' % (','.join(missing_args)))
  return ret


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('field', type=str, nargs='?',
                      help='information field')
  args = parser.parse_args()

  hammerd_args = GetHammerdArguments()
  updater = hammerd_api.FirmwareUpdater(
      int(hammerd_args['VENDOR_ID']), int(hammerd_args['PRODUCT_ID']),
      hammerd_args['USB_PATH'])
  with open(hammerd_args['EC_IMAGE_PATH'], 'rb') as f:
    ec_image = f.read()
  updater.LoadEcImage(ec_image)
  updater.TryConnectUsb()
  updater.SendFirstPdu()
  updater.SendDone()

  pdu_resp = updater.GetFirstResponsePdu().contents
  wp_status = (pdu_resp.flash_protection & EC_FLASH_PROTECT_GPIO_ASSERTED) > 0
  wp_all = pdu_resp.flash_protection == FLASH_PROTECT_ALL
  touchpad_info = hammerd_api.TouchpadInfo()
  updater.SendSubcommandReceiveResponse(
      hammerd_api.UpdateExtraCommand.TouchpadInfo, '',
      ctypes.pointer(touchpad_info), ctypes.sizeof(touchpad_info))

  # Do a pairing challenge, which will check that entropy has been injected
  pair_manager = hammerd_api.PairManager()
  challenge_status = pair_manager.PairChallenge(updater.object, None)

  # Print the base information.
  info = collections.OrderedDict()
  info['ro_version'] = updater.GetSectionVersion(hammerd_api.SectionName.RO)
  info['rw_version'] = updater.GetSectionVersion(hammerd_api.SectionName.RW)
  info['key_version'] = pdu_resp.key_version
  info['wp_screw'] = str(wp_status)
  info['wp_all'] = str(wp_all)
  info['challenge_status'] = hammerd_api.ChallengeStatus.ToStr(challenge_status)
  info['touchpad_id'] = '%d.0' % touchpad_info.id
  info['touchpad_pid'] = hex(touchpad_info.vendor)
  info['touchpad_fw_version'] = '%d.0' % touchpad_info.fw_version
  info['touchpad_fw_checksum'] = hex(touchpad_info.fw_checksum)

  if args.field is None:
    print(' '.join('%s="%s"' % (key, val) for key, val in info.items()))
  elif args.field in info:
    print(info[args.field])
  else:
    print('Invalid args.field: "%s", should be one of %s' %
          (args.field, ', '.join(info.keys())))
    exit(1)


if __name__ == '__main__':
  main()
