# 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.

"""Tests for the command module."""

import argparse
import importlib
import os

from chromite.cli import command
from chromite.lib import commandline
from chromite.lib import cros_test_lib
from chromite.lib import partial_mock


# pylint:disable=protected-access

_COMMAND_NAME = "superAwesomeCommandOfFunness"


@command.command_decorator(_COMMAND_NAME)
class TestCommand(command.CliCommand):
    """A fake command."""

    def Run(self):
        print("Just testing")


class TestCommandTest(cros_test_lib.MockTestCase):
    """This test class tests that Commands method."""

    def testParserSetsCommandClass(self):
        """Tests that our parser sets command_class correctly."""
        my_parser = argparse.ArgumentParser()
        command.CliCommand.AddParser(my_parser)
        ns = my_parser.parse_args([])
        self.assertEqual(ns.command_class, command.CliCommand)

    def testCommandDecorator(self):
        """Tests that our decorator correctly adds TestCommand to _commands."""
        # Note this exposes an implementation detail of _commands.
        self.assertEqual(command._commands[_COMMAND_NAME], TestCommand)

    def testBadUseOfCommandDecorator(self):
        """Tests that our decorator correctly rejects bad test commands."""
        try:
            # pylint: disable=unused-variable
            @command.command_decorator("bad")
            class BadTestCommand:
                """A command that wasn't implemented correctly."""

        except command.InvalidCommandError:
            pass
        else:
            self.fail("Invalid command was accepted by @command_decorator")

    def testAddDeviceArgument(self):
        """Tests CliCommand.AddDeviceArgument()."""
        parser = argparse.ArgumentParser()
        command.CliCommand.AddDeviceArgument(parser, positional=True)
        # Device should be a positional argument.
        parser.parse_args(["device"])

    def testAddNamedDeviceArgument(self):
        """Tests CliCommand.AddDeviceArgument()."""
        parser = argparse.ArgumentParser()
        command.CliCommand.AddDeviceArgument(parser, positional=False)
        # Device should be a named argument.
        parser.parse_args(["--device=device"])
        parser.parse_args(["-d", "device"])


class MockCommand(partial_mock.PartialMock):
    """Mock class for a generic CLI command."""

    ATTRS = ("Run",)
    COMMAND = None
    TARGET_CLASS = None

    def __init__(self, args, base_args=None):
        partial_mock.PartialMock.__init__(self)
        self.args = args
        self.rc_mock = cros_test_lib.RunCommandMock()
        self.rc_mock.SetDefaultCmdResult()
        self.parser = parser = commandline.ArgumentParser(caching=True)
        subparsers = parser.add_subparsers()
        subparser = subparsers.add_parser(
            self.COMMAND,
            caching=self.TARGET_CLASS.use_caching_options,
            dryrun=self.TARGET_CLASS.use_dryrun_options,
        )
        self.TARGET_CLASS.AddParser(subparser)

        args = base_args if base_args else []
        args += [self.COMMAND] + self.args
        options = parser.parse_args(args)
        self.inst = options.command_class(options)

    def Run(self, inst):
        with self.rc_mock:
            return self.backup["Run"](inst)


class CommandTest(cros_test_lib.MockTestCase):
    """This test class tests that we can load modules correctly."""

    def testFindModules(self):
        """Tests that we can return modules correctly when mocking out glob."""
        fake_command_file = "cros_command_test.py"
        filtered_file = "cros_command_unittest.py"

        self.PatchObject(
            os, "listdir", return_value=[fake_command_file, filtered_file]
        )

        self.assertEqual(command.ListCommands(), {"command-test"})

    def testLoadCommands(self):
        """Tests import commands correctly."""
        fake_module = "cros_command_test"
        module_path = "chromite.cli.cros.%s" % fake_module

        # The code doesn't use the return value, so stub it out lazy-like.
        load_mock = self.PatchObject(
            importlib, "import_module", return_value=None
        )

        command._commands["command-test"] = 123
        self.assertEqual(command.ImportCommand("command-test"), 123)
        command._commands.pop("command-test")

        load_mock.assert_called_with(module_path)

    def testListCrosCommands(self):
        """Tests we get a correct `cros` list back."""
        cros_commands = command.ListCommands()
        # Pick some commands that are likely to not go away.
        self.assertIn("chrome-sdk", cros_commands)
        self.assertIn("flash", cros_commands)
