# -*- coding: utf-8 -*-
# Copyright (c) 2012 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 build command."""

from __future__ import print_function

from chromite.cli import command
from chromite.cli import command_unittest
from chromite.cli.cros import cros_build
from chromite.lib import chroot_util
from chromite.lib import cros_logging as logging
from chromite.lib import cros_test_lib
from chromite.lib import parallel_unittest
from chromite.lib import partial_mock
from chromite.lib import workon_helper


class MockBuildCommand(command_unittest.MockCommand):
  """Mock out the build command."""
  TARGET = 'chromite.cli.cros.cros_build.BuildCommand'
  TARGET_CLASS = cros_build.BuildCommand

  def __init__(self, *args, **kwargs):
    super(MockBuildCommand, self).__init__(*args, **kwargs)
    self.chroot_update_called = 0

  def OnChrootUpdate(self, *_args, **_kwargs):
    self.chroot_update_called += 1

  def Run(self, inst):
    self.PatchObject(chroot_util, 'UpdateChroot',
                     side_effect=self.OnChrootUpdate)
    self.PatchObject(chroot_util, 'Emerge')
    with parallel_unittest.ParallelMock():
      command_unittest.MockCommand.Run(self, inst)


class FakeWorkonHelper(object):
  """Fake workon_helper.WorkonHelper."""

  def __init__(self, *_args, **_kwargs):
    self.start_called = 0
    self.use_workon_only = None

  def ListAtoms(self, *_args, **_kwargs):
    pass

  def StartWorkingOnPackages(self, *_args, **kwargs):
    self.start_called += 1
    self.use_workon_only = kwargs.get('use_workon_only')


class BuildCommandTest(cros_test_lib.MockTempDirTestCase,
                       cros_test_lib.OutputTestCase):
  """Test class for our BuildCommand class."""

  def testBrilloBuildOperationCalled(self):
    """Test that BrilloBuildOperation is used when appropriate."""
    cmd = ['--board=randonname', 'power_manager']
    self.PatchObject(workon_helper, 'WorkonHelper')
    self.PatchObject(command, 'UseProgressBar', return_value=True)
    with MockBuildCommand(cmd) as build:
      operation_run = self.PatchObject(cros_build.BrilloBuildOperation, 'Run')
      build.inst.Run()
      self.assertTrue(operation_run.called)

  def testBrilloBuildOperationNotCalled(self):
    """Test that BrilloBuildOperation is not used when it shouldn't be."""
    cmd = ['--board=randonname', 'power_manager']
    self.PatchObject(workon_helper, 'WorkonHelper')
    self.PatchObject(command, 'UseProgressBar', return_value=False)
    with MockBuildCommand(cmd) as build:
      operation_run = self.PatchObject(cros_build.BrilloBuildOperation, 'Run')
      build.inst.Run()
      self.assertFalse(operation_run.called)

  def testSuccess(self):
    """Test that successful commands work."""
    cmds = [['--host', 'power_manager'],
            ['--board=randomname', 'power_manager'],
            ['--board=randomname', '--debug', 'power_manager'],
            ['--board=randomname', '--no-deps', 'power_manager'],
            ['--board=randomname', '--no-chroot-update', 'power_manager'],
            ['--board=randomname', '--no-enable-only-latest', 'power_manager']]
    for cmd in cmds:
      update_chroot = not ('--no-deps' in cmd or '--no-chroot-update' in cmd)
      enable_only_latest = '--no-enable-only-latest' not in cmd
      fake_workon_helper = FakeWorkonHelper()
      self.PatchObject(workon_helper, 'WorkonHelper',
                       return_value=fake_workon_helper)
      with MockBuildCommand(cmd) as build:
        build.inst.Run()
        self.assertEqual(1 if update_chroot else 0, build.chroot_update_called)
        self.assertEqual(1 if enable_only_latest else 0,
                         fake_workon_helper.start_called)
        self.assertEqual(True if enable_only_latest else None,
                         fake_workon_helper.use_workon_only)

  def testFailedDeps(self):
    """Test that failures are detected correctly."""
    # pylint: disable=protected-access
    args = ['--board=randomname', 'power_manager']
    self.PatchObject(workon_helper, 'WorkonHelper',
                     return_value=FakeWorkonHelper())
    with MockBuildCommand(args) as build:
      cmd = partial_mock.In('--backtrack=0')
      build.rc_mock.AddCmdResult(cmd=cmd, returncode=1, error='error\n')
      with self.OutputCapturer():
        try:
          build.inst.Run()
        except Exception as e:
          logging.error(e)
      self.AssertOutputContainsError(cros_build.BuildCommand._BAD_DEPEND_MSG,
                                     check_stderr=True)
