#!/usr/bin/python
# Copyright (c) 2013 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.

"""This module tests the cros flash command."""

from __future__ import print_function

import mock
import os
import sys

sys.path.insert(0, os.path.abspath('%s/../../..' % os.path.dirname(__file__)))
from chromite.cros.commands import cros_flash
from chromite.cros.commands import init_unittest
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import dev_server_wrapper
from chromite.lib import partial_mock
from chromite.lib import remote_access


# pylint: disable=W0212
class TestXbuddyHelpers(cros_test_lib.MockTempDirTestCase):
  """Test xbuddy helper functions."""
  def testGenerateXbuddyRequestForUpdate(self):
    """Test we generate correct xbuddy requests."""
    # Use the latest build when 'latest' is given.
    req = 'xbuddy/latest?for_update=true&return_dir=true'
    self.assertEqual(
        cros_flash.GenerateXbuddyRequest('latest', 'update'), req)

    # Convert the path starting with 'xbuddy://' to 'xbuddy/'
    path = 'xbuddy://remote/stumpy/version'
    req = 'xbuddy/remote/stumpy/version?for_update=true&return_dir=true'
    self.assertEqual(cros_flash.GenerateXbuddyRequest(path, 'update'), req)

  def testGenerateXbuddyRequestForImage(self):
    """Tests that we generate correct requests to get images."""
    image_path = 'foo/bar/taco'
    self.assertEqual(cros_flash.GenerateXbuddyRequest(image_path, 'image'),
                     'xbuddy/foo/bar/taco?return_dir=true')

    image_path = 'xbuddy://foo/bar/taco'
    self.assertEqual(cros_flash.GenerateXbuddyRequest(image_path, 'image'),
                     'xbuddy/foo/bar/taco?return_dir=true')

  def testGenerateXbuddyRequestForTranslate(self):
    """Tests that we generate correct requests for translation."""
    image_path = 'foo/bar/taco'
    self.assertEqual(cros_flash.GenerateXbuddyRequest(image_path, 'translate'),
                     'xbuddy_translate/foo/bar/taco')

    image_path = 'xbuddy://foo/bar/taco'
    self.assertEqual(cros_flash.GenerateXbuddyRequest(image_path, 'translate'),
                     'xbuddy_translate/foo/bar/taco')

  def testConvertTranslatedPath(self):
    """Tests that we convert a translated path to a usable xbuddy path."""
    path = 'remote/latest-canary'
    translated_path = 'taco-release/R36-5761.0.0/chromiumos_test_image.bin'
    self.assertEqual(cros_flash.ConvertTranslatedPath(path, translated_path),
                     'remote/taco-release/R36-5761.0.0/test')

    path = 'latest'
    translated_path = 'taco/R36-5600.0.0/chromiumos_image.bin'
    self.assertEqual(cros_flash.ConvertTranslatedPath(path, translated_path),
                     'local/taco/R36-5600.0.0/dev')

  @mock.patch('chromite.lib.cros_build_lib.IsInsideChroot', return_value=True)
  def testDevserverURLToLocalPath(self, _mock1):
    """Tests that we convert a devserver URL to a local path correctly."""
    url = 'http://localhost:8080/static/peppy-release/R33-5116.87.0'
    base_path = os.path.join(self.tempdir, 'peppy-release/R33-5116.87.0')

    local_path = os.path.join(base_path, 'recovery_image.bin')
    self.assertEqual(
      cros_flash.DevserverURLToLocalPath(
          url, self.tempdir, 'recovery'), local_path)

    # Default to test image.
    local_path = os.path.join(base_path, 'chromiumos_test_image.bin')
    self.assertEqual(
      cros_flash.DevserverURLToLocalPath(url, self.tempdir, 'taco'), local_path)


class MockFlashCommand(init_unittest.MockCommand):
  """Mock out the flash command."""
  TARGET = 'chromite.cros.commands.cros_flash.FlashCommand'
  TARGET_CLASS = cros_flash.FlashCommand
  COMMAND = 'flash'

  def __init__(self, *args, **kwargs):
    init_unittest.MockCommand.__init__(self, *args, **kwargs)

  def Run(self, inst):
    init_unittest.MockCommand.Run(self, inst)


class RemoteDeviceUpdaterMock(partial_mock.PartialCmdMock):
  """Mock out RemoteDeviceUpdater."""
  TARGET = 'chromite.cros.commands.cros_flash.RemoteDeviceUpdater'
  ATTRS = ('UpdateStateful', 'UpdateRootfs', 'GetUpdatePayloads',
           'SetupRootfsUpdate', 'Verify')

  def __init__(self):
    partial_mock.PartialCmdMock.__init__(self)

  def GetUpdatePayloads(self, _inst, *_args, **_kwargs):
    """Mock out GetUpdatePayloads."""

  def UpdateStateful(self, _inst, *_args, **_kwargs):
    """Mock out UpdateStateful."""

  def UpdateRootfs(self, _inst, *_args, **_kwargs):
    """Mock out UpdateRootfs."""

  def SetupRootfsUpdate(self, _inst, *_args, **_kwargs):
    """Mock out SetupRootfsUpdate."""

  def Verify(self, _inst, *_args, **_kwargs):
    """Mock out SetupRootfsUpdate."""


class UpdateRunThroughTest(cros_test_lib.MockTempDirTestCase,
                           cros_test_lib.LoggingTestCase):
  """Test the flow of FlashCommand.run with the update methods mocked out."""

  IMAGE = '/path/to/image'
  DEVICE = '1.1.1.1'

  def SetupCommandMock(self, cmd_args):
    """Setup comand mock."""
    self.cmd_mock = MockFlashCommand(
        cmd_args, base_args=['--cache-dir', self.tempdir])
    self.StartPatcher(self.cmd_mock)

  def setUp(self):
    """Patches objects."""
    self.cmd_mock = None
    self.updater_mock = self.StartPatcher(RemoteDeviceUpdaterMock())
    self.PatchObject(cros_flash, 'GenerateXbuddyRequest',
                     return_value='xbuddy/local/latest')
    self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
    self.PatchObject(cros_flash, 'TranslateImagePath',
                     return_value='taco-paladin/R36/chromiumos_test_image.bin')
    self.PatchObject(remote_access, 'CHECK_INTERVAL', new=0)
    self.PatchObject(remote_access.ChromiumOSDevice, '_LearnBoard',
                     return_value='peppy')

  def testUpdateAll(self):
    """Tests that update methods are called correctly."""
    self.SetupCommandMock([self.DEVICE, self.IMAGE])
    with mock.patch('os.path.exists', return_value=True):
      self.cmd_mock.inst.Run()
      self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
      self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)

  def testUpdateStateful(self):
    """Tests that update methods are called correctly."""
    self.SetupCommandMock(['--no-rootfs-update', self.DEVICE, self.IMAGE])
    with mock.patch('os.path.exists', return_value=True):
      self.cmd_mock.inst.Run()
      self.assertTrue(self.updater_mock.patched['UpdateStateful'].called)
      self.assertFalse(self.updater_mock.patched['UpdateRootfs'].called)

  def testUpdateRootfs(self):
    """Tests that update methods are called correctly."""
    self.SetupCommandMock(['--no-stateful-update', self.DEVICE, self.IMAGE])
    with mock.patch('os.path.exists', return_value=True):
      self.cmd_mock.inst.Run()
      self.assertFalse(self.updater_mock.patched['UpdateStateful'].called)
      self.assertTrue(self.updater_mock.patched['UpdateRootfs'].called)

  def testMissingPayloads(self):
    """Tests we exit when payloads are missing."""
    self.SetupCommandMock([self.DEVICE, self.IMAGE])
    with mock.patch('os.path.exists', return_value=False):
      self.assertRaises(cros_build_lib.DieSystemExit, self.cmd_mock.inst.Run)


class USBImagerMock(partial_mock.PartialCmdMock):
  """Mock out USBImager."""
  TARGET = 'chromite.cros.commands.cros_flash.USBImager'
  ATTRS = ('GetImagePathFromDevserver', 'CopyImageToDevice',
           'InstallImageToDevice', 'ChooseRemovableDevice',
           'ListAllRemovableDevices', 'GetRemovableDeviceDescription',
           'IsFilePathGPTDiskImage')
  VALID_IMAGE = True

  def __init__(self):
    partial_mock.PartialCmdMock.__init__(self)

  def GetImagePathFromDevserver(self, _inst, *_args, **_kwargs):
    """Mock out GetImagePathFromDevserver."""

  def CopyImageToDevice(self, _inst, *_args, **_kwargs):
    """Mock out CopyImageToDevice."""

  def InstallImageToDevice(self, _inst, *_args, **_kwargs):
    """Mock out InstallImageToDevice."""

  def ChooseRemovableDevice(self, _inst, *_args, **_kwargs):
    """Mock out ChooseRemovableDevice."""

  def ListAllRemovableDevices(self, _inst, *_args, **_kwargs):
    """Mock out ListAllRemovableDevices."""
    return ['foo', 'taco', 'milk']

  def GetRemovableDeviceDescription(self, _inst, *_args, **_kwargs):
    """Mock out GetRemovableDeviceDescription."""

  def IsFilePathGPTDiskImage(self, _inst, *_args, **_kwargs):
    """Mock out IsFilePathGPTDiskImage."""
    return self.VALID_IMAGE


class ImagingRunThroughTest(cros_test_lib.MockTempDirTestCase,
                            cros_test_lib.LoggingTestCase):
  """Test the flow of FlashCommand.run with the imaging methods mocked out."""
  IMAGE = '/path/to/image'

  def SetupCommandMock(self, cmd_args):
    """Setup comand mock."""
    self.cmd_mock = MockFlashCommand(
        cmd_args, base_args=['--cache-dir', self.tempdir])
    self.StartPatcher(self.cmd_mock)

  def setUp(self):
    """Patches objects."""
    self.cmd_mock = None
    self.usb_mock = USBImagerMock()
    self.imager_mock = self.StartPatcher(self.usb_mock)
    self.PatchObject(cros_flash, 'GenerateXbuddyRequest',
                     return_value='xbuddy/local/latest')
    self.PatchObject(dev_server_wrapper, 'DevServerWrapper')
    self.PatchObject(cros_flash, 'TranslateImagePath',
                     return_value='taco-paladin/R36/chromiumos_test_image.bin')
    self.PatchObject(os.path, 'exists', return_value=True)

  def testLocalImagePathCopy(self):
    """Tests that imaging methods are called correctly."""
    self.SetupCommandMock(['usb:///dev/foo', self.IMAGE])
    with mock.patch('os.path.isfile', return_value=True):
      self.cmd_mock.inst.Run()
      self.assertTrue(self.imager_mock.patched['CopyImageToDevice'].called)

  def testLocalImagePathInstall(self):
    """Tests that imaging methods are called correctly."""
    self.SetupCommandMock(['--board=taco', '--install', 'usb:///dev/foo',
                           self.IMAGE])
    with mock.patch('os.path.isfile', return_value=True):
      self.cmd_mock.inst.Run()
      self.assertTrue(self.imager_mock.patched['InstallImageToDevice'].called)

  def testLocalBadImagePath(self):
    """Tests that using an image not having the magic bytes has prompt."""
    self.usb_mock.VALID_IMAGE = False
    self.SetupCommandMock(['usb:///dev/foo', self.IMAGE])
    with mock.patch('os.path.isfile', return_value=True):
      with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
        mock_prompt.return_value = False
        self.cmd_mock.inst.Run()
        self.assertTrue(mock_prompt.called)

  def testNonLocalImgePath(self):
    """Tests that we try to get the image path from devserver."""
    self.SetupCommandMock(['usb:///dev/foo', self.IMAGE])
    with mock.patch('os.path.isfile', return_value=False):
      with mock.patch('os.path.isdir', return_value=False):
        self.cmd_mock.inst.Run()
        self.assertTrue(
            self.imager_mock.patched['GetImagePathFromDevserver'].called)
        self.assertTrue(self.imager_mock.patched['CopyImageToDevice'].called)

  def testConfirmNonRemovableDevice(self):
    """Tests that we ask user to confirm if the device is not removable."""
    with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
      self.SetupCommandMock(['usb:///dev/dummy', self.IMAGE])
      self.cmd_mock.inst.Run()
      self.assertTrue(mock_prompt.called)

  def testSkipPromptNonRemovableDevice(self):
    """Tests that we skip the prompt for non-removable with --yes."""
    with mock.patch.object(cros_build_lib, 'BooleanPrompt') as mock_prompt:
      self.SetupCommandMock(['--yes', 'usb:///dev/dummy', self.IMAGE])
      self.cmd_mock.inst.Run()
      self.assertFalse(mock_prompt.called)

  def testChooseRemovableDevice(self):
    """Tests that we ask user to choose a device if none is given."""
    self.SetupCommandMock(['usb://', self.IMAGE])
    self.cmd_mock.inst.Run()
    self.assertTrue(self.imager_mock.patched['ChooseRemovableDevice'].called)


if __name__ == '__main__':
  cros_test_lib.main()
