# Copyright 2021 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Update vendor plugin firmware using fwupdtool.

Description
-----------
This test updates the vendor plugin firmware by calling fwupdtool. User has to
specify the path to firmware and also the name of the plugin to be updated.

Test Procedure
--------------
This is an automatic test that doesn't need any user interaction.

1. Firstly, this test will create a DUT link.
2. If the firmware image is from the station, the image would be sent to DUT.
3. If the firmware image is in release partition, the test mounts the release
   partition to get the image.
4. If the firmware image is in test partition, the test mounts the test
   partition to get the image.

Dependency
----------
- DUT link must be ready before running this test.
- `fwupdtool` on DUT.

Examples
--------
To update the nvme firmware with the image in DUT release partition,
add this in test list::

  {
    "pytest_name": "update_plugin_firmware",
    "args": {
      "firmware_file": "/path/to/firmware/file/image.cab",
      "plugin": "nvme"
    }
  }

To update the nvme firmware with the image in DUT test partition,
and allow downgrading the firmware version, add this in test list::

  {
    "pytest_name": "update_plugin_firmware",
    "args": {
      "allow_older": true,
      "firmware_file": "/path/to/firmware/file/image.cab",
      "from_release": false,
      "plugin": "nvme"
    }
  }
"""

import logging

from cros.factory.device import device_utils
from cros.factory.test import test_case
from cros.factory.test import test_ui
from cros.factory.utils.arg_utils import Arg
from cros.factory.utils import sys_utils


FWUPDTOOL = 'fwupdtool'


class UpdateUsingFwUpdTest(test_case.TestCase):
  related_components = tuple()

  ARGS = [
      Arg('allow_older', bool, 'Allow downgrading the firmware.',
          default=False),
      Arg('firmware_file', str, 'Name of the firmware binary file (.cab).'),
      Arg('from_release', bool, 'Get the firmware file from release rootfs.',
          default=True),
      Arg('plugin', str, 'Specify the name of the plugin.'),
  ]

  ui_class = test_ui.ScrollableLogUI

  def setUp(self):
    self._dut = device_utils.CreateDUTInterface()
    # yapf: disable
    self._allow_older = self.args.allow_older  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable
    self._firmware_file = None
    # yapf: disable
    self._from_release = self.args.from_release  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable
    # yapf: disable
    self._plugin = self.args.plugin  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable

  def runTest(self):
    # yapf: disable
    if self.args.from_release:  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
      # yapf: enable
      logging.info('Get firmware from release rootfs...')
      with sys_utils.MountPartition(self._dut.partitions.RELEASE_ROOTFS.path,
                                    dut=self._dut) as root:
        self._firmware_file = self._dut.path.join(root,
                                                  # yapf: disable
                                                  self.args.firmware_file[1:])  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
        # yapf: enable
        self.UpdatePlugin()
    else:
      if self._dut.link.IsLocal():
        # yapf: disable
        self._firmware_file = self.args.firmware_file  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
        # yapf: enable
        self.UpdatePlugin()
      else:
        with self._dut.temp.TempFile() as dut_temp_file:
          # yapf: disable
          self._dut.SendFile(self.args.firmware_file, dut_temp_file)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
          # yapf: enable
          self._firmware_file = dut_temp_file
          self.UpdatePlugin()

  def UpdatePlugin(self):
    # Skip reboot prompt by adding `--no-reboot-check`.
    update_command = [FWUPDTOOL, 'install', '--no-reboot-check']

    # We add `nocheck` in the comment to skip the blocked_term checking.
    # In older version of fwupdtool, the option `--plugins` is called
    # `--plugin-whitelist`. nocheck
    support_plugins = self._dut.CallOutput(
        f'{FWUPDTOOL} --help | grep -- --plugins')

    if support_plugins:
      update_command += ['--plugins', self._plugin]
    else:
      update_command += ['--plugin-whitelist', self._plugin]  # nocheck

    if self._allow_older:
      update_command += ['--allow-older']
      logging.warning('Allow downgrading plugin %s firmware.', self._plugin)

    # yapf: disable
    update_command += [self._firmware_file]  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable
    logging.info('Update plugins: %s', update_command)
    # yapf: disable
    returncode = self.ui.PipeProcessOutputToUI(update_command)  # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
    # yapf: enable

    self.assertEqual(returncode, 0,
                     f'Firmware update failed: {int(returncode)}.')
