class Rundeck(BasePlugin):

    def __init__(self):
        super().__init__("Rundeck")
        self.load_config()

    def load_config(self):  # pragma: no cover
        config_dict = configuration.get()
        self.rundeck_token = config_dict['rundeck']['token']
        self.rundeck_url = config_dict['rundeck']['url']
        try:
            # It's okay if this key isn't set
            self.topic_channel = config_dict['rundeck']['deployment_status_channel']  # NOQA
        except KeyError:
            self.topic_channel = None
        self.rd_jobs_raw_list = config_dict['rundeck']['lock_jobs']
        self.rundeck_lock = RundeckLock(self.rundeck_token,
                                        self.rundeck_url,
                                        self.topic_channel,
                                        self.rd_jobs_raw_list)

    def get_help_message(self):
        help_msg = []
        help_msg.append("!lock status - Prints the status of the Rundeck deployment lock")  # NOQA
        help_msg.append("!lock acquire - Acquires the Rundeck deployment lock (only available to Slack admins)")  # NOQA
        help_msg.append("!lock release - Releases the Rundeck deployment lock (only available to Slack admins)")  # NOQA
        return "\n".join(help_msg)

    @asyncio.coroutine
    def process_message(self, message):
        """
        Main method that handles all messages sent to this plugin
        """
        if not type(message) is SlackMessage:
            return

        parsed_message = parse_msg_with_prefix("!lock", message.text)
        if not parsed_message:
            return

        if does_msg_contain_prefix("acquire", parsed_message):
            yield from self.rundeck_lock.toggle_rundeck_lock(message,
                                                             lock_job=True)
        elif does_msg_contain_prefix("release", parsed_message):
            yield from self.rundeck_lock.toggle_rundeck_lock(message,
                                                             lock_job=False)
        elif does_msg_contain_prefix("status", parsed_message):
            yield from self.rundeck_lock.print_lock_status(message)
class TestPrintLockStatus(asynctest.TestCase):

    def setUp(self):
        patcher1 = patch('charlesbot_rundeck.rundeck_lock.RundeckLock.seed_job_list')  # NOQA
        self.addCleanup(patcher1.stop)
        self.mock_seed_job_list = patcher1.start()

        from charlesbot_rundeck.rundeck_lock import RundeckLock
        self.rd_lock = RundeckLock("token",
                                   "url",
                                   "channel",
                                   [])
        self.rd_lock.slack.send_channel_message = CoroutineMock()
        self.rd_lock.trigger_rundeck_executions_allowed_update = CoroutineMock()  # NOQA
        self.sm = SlackMessage(channel="sixchan")

    def test_empty_job_list(self):
        self.rd_lock.rundeck_jobs = []
        expected_slack_msg_raw = []
        expected_slack_msg_raw.append("*Rundeck Job Lock Report*")
        expected_slack_msg_raw.append("```")
        expected_slack_msg_raw.append("```")
        expected_slack_msg = "\n".join(expected_slack_msg_raw)
        expected_call = call("sixchan", expected_slack_msg)
        yield from self.rd_lock.print_lock_status(self.sm)
        self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls,
                         [expected_call])

    def test_single_enabled_job(self):
        self.rd_lock.rundeck_jobs = [
            RundeckJob(friendly_name="job1", execution_enabled=True)
        ]
        expected_slack_msg_raw = []
        expected_slack_msg_raw.append("*Rundeck Job Lock Report*")
        expected_slack_msg_raw.append("```")
        expected_slack_msg_raw.append("job1: unlocked")
        expected_slack_msg_raw.append("```")
        expected_slack_msg = "\n".join(expected_slack_msg_raw)
        expected_call = call("sixchan", expected_slack_msg)
        yield from self.rd_lock.print_lock_status(self.sm)
        self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls,
                         [expected_call])

    def test_single_disabled_job(self):
        self.rd_lock.rundeck_jobs = [
            RundeckJob(friendly_name="job1", execution_enabled=False)
        ]
        expected_slack_msg_raw = []
        expected_slack_msg_raw.append("*Rundeck Job Lock Report*")
        expected_slack_msg_raw.append("```")
        expected_slack_msg_raw.append("job1: locked")
        expected_slack_msg_raw.append("```")
        expected_slack_msg = "\n".join(expected_slack_msg_raw)
        expected_call = call("sixchan", expected_slack_msg)
        yield from self.rd_lock.print_lock_status(self.sm)
        self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls,
                         [expected_call])

    def test_multiple_mixed_jobs(self):
        self.rd_lock.rundeck_jobs = [
            RundeckJob(friendly_name="job1", execution_enabled=False),
            RundeckJob(friendly_name="job3", execution_enabled=True),
            RundeckJob(friendly_name="job2", execution_enabled=False)
        ]
        expected_slack_msg_raw = []
        expected_slack_msg_raw.append("*Rundeck Job Lock Report*")
        expected_slack_msg_raw.append("```")
        expected_slack_msg_raw.append("job1: locked")
        expected_slack_msg_raw.append("job3: unlocked")
        expected_slack_msg_raw.append("job2: locked")
        expected_slack_msg_raw.append("```")
        expected_slack_msg = "\n".join(expected_slack_msg_raw)
        expected_call = call("sixchan", expected_slack_msg)
        yield from self.rd_lock.print_lock_status(self.sm)
        self.assertEqual(self.rd_lock.slack.send_channel_message.mock_calls,
                         [expected_call])