# Copyright 2012 The ChromiumOS Authors
# 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."""

import logging

import pytest  # pylint: disable=import-error

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_test_lib
from chromite.lib import parallel_unittest
from chromite.lib import partial_mock
from chromite.lib import workon_helper


pytestmark = cros_test_lib.pytestmark_inside_only


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().__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")


@pytest.mark.usefixtures("testcase_caplog")
class BuildCommandTest(cros_test_lib.MockTempDirTestCase):
    """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, stderr="error\n")
            try:
                build.inst.Run()
            except Exception as e:
                logging.error(e)

            self.assertIn(
                cros_build.BuildCommand._BAD_DEPEND_MSG, self.caplog.text
            )
