#!/usr/bin/env python3
# Copyright 2017 The ChromiumOS Authors
# 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 os.path
import shlex
import subprocess
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
)

# list of pre-defined exit codes
ERROR_GET_FIRST_PDU = 3


def DetachableBaseConfig(key, check=True):
    cmd = ["cros_config", "/detachable-base", key]
    proc = subprocess.run(
        cmd, encoding="utf-8", check=check, capture_output=True
    )
    return None if proc.returncode else proc.stdout


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",
    ]
    IMAGE_DIR = "/lib/firmware"

    ret = {}
    if os.path.exists(ARGUMENT_FILE_PATH):
        with open(ARGUMENT_FILE_PATH, "r", encoding="utf-8") 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
    else:
        ec_image_filename = DetachableBaseConfig("ec-image-name")
        touchpad_image_filename = DetachableBaseConfig("touch-image-name")

        ret["EC_IMAGE_PATH"] = os.path.join(IMAGE_DIR, ec_image_filename)
        ret["TOUCHPAD_IMAGE_PATH"] = os.path.join(
            IMAGE_DIR, touchpad_image_filename
        )
        ret["VENDOR_ID"] = DetachableBaseConfig("vendor-id")
        ret["PRODUCT_ID"] = DetachableBaseConfig("product-id")
        ret["USB_PATH"] = DetachableBaseConfig("usb-path", check=False)
        ret["I2C_PATH"] = DetachableBaseConfig("i2c-path", check=False)

    missing_args = set(REQUIRED_ARGUMENTS) - set(ret.keys())
    if missing_args:
        raise ValueError("Missing arguments: %s" % (",".join(missing_args)))
    if "USB_PATH" not in ret and "I2C_PATH" not in ret:
        raise ValueError("Require at least one of USB_PATH or I2C_PATH")
    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"]),
        usb_path=hammerd_args["USB_PATH"],
        i2c_path=hammerd_args["I2C_PATH"],
    )
    with open(hammerd_args["EC_IMAGE_PATH"], "rb") as f:
        ec_image = f.read()
    updater.LoadEcImage(ec_image)
    updater.TryConnectUsb()
    if not updater.SendFirstPdu():
        sys.exit(ERROR_GET_FIRST_PDU)
    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,
        b"",
        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()
