#!/usr/bin/env python3
# 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 sys

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())))
    sys.exit(1)


if __name__ == '__main__':
  main()
