# Copyright 2017, OpenStack Foundation
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
#

from osc_lib.command import command

from mistralclient.commands.v2 import base
from mistralclient import utils


class EventTriggerFormatter(base.MistralFormatter):
    COLUMNS = [
        ('id', 'ID'),
        ('name', 'Name'),
        ('workflow_id', 'Workflow ID'),
        ('workflow_params', 'Params'),
        ('exchange', 'Exchange'),
        ('topic', 'Topic'),
        ('event', 'Event'),
        ('created_at', 'Created at'),
        ('updated_at', 'Updated at')
    ]

    @staticmethod
    def format(trigger=None, lister=False):
        if trigger:
            data = (
                trigger.id,
                trigger.name,
                trigger.workflow_id,
                trigger.workflow_params,
                trigger.exchange,
                trigger.topic,
                trigger.event,
                trigger.created_at,
            )

            if hasattr(trigger, 'updated_at'):
                data += (trigger.updated_at,)
            else:
                data += (None,)
        else:
            data = (tuple('' for _ in
                          range(len(EventTriggerFormatter.COLUMNS))),)

        return EventTriggerFormatter.headings(), data


class List(base.MistralLister):
    """List all event triggers."""

    def _get_format_function(self):
        return EventTriggerFormatter.format_list

    def _get_resources(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine
        return mistral_client.event_triggers.list(
            marker=parsed_args.marker,
            limit=parsed_args.limit,
            sort_keys=parsed_args.sort_keys,
            sort_dirs=parsed_args.sort_dirs,
            fields=EventTriggerFormatter.fields(),
            **base.get_filters(parsed_args)
        )


class Get(command.ShowOne):
    """Show specific event trigger."""

    def get_parser(self, prog_name):
        parser = super(Get, self).get_parser(prog_name)

        parser.add_argument('event_trigger', help='Event trigger ID')

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine

        return EventTriggerFormatter.format(mistral_client.event_triggers.get(
                                            parsed_args.event_trigger))


class Create(command.ShowOne):
    """Create new trigger."""

    def get_parser(self, prog_name):
        parser = super(Create, self).get_parser(prog_name)

        parser.add_argument('name', help='Event trigger name')
        parser.add_argument('workflow_id', help='Workflow ID')

        parser.add_argument('exchange',
                            type=str,
                            help='Event trigger exchange')

        parser.add_argument('topic',
                            type=str,
                            help='Event trigger topic')

        parser.add_argument('event',
                            type=str,
                            help='Event trigger event name')

        parser.add_argument('workflow_input',
                            nargs='?',
                            help='Workflow input')

        parser.add_argument('--params',
                            help='Workflow params')

        return parser

    @staticmethod
    def _get_json_string_or_dict(string):
        if string:
            return utils.load_json(string)
        else:
            return {}

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine

        wf_input = self._get_json_string_or_dict(parsed_args.workflow_input)
        wf_params = self._get_json_string_or_dict(parsed_args.params)

        trigger = mistral_client.event_triggers.create(
            parsed_args.name,
            parsed_args.workflow_id,
            parsed_args.exchange,
            parsed_args.topic,
            parsed_args.event,
            wf_input,
            wf_params,
        )

        return EventTriggerFormatter.format(trigger)


class Delete(command.Command):
    """Delete trigger."""

    def get_parser(self, prog_name):
        parser = super(Delete, self).get_parser(prog_name)

        parser.add_argument(
            'event_trigger_id',
            nargs='+', help='ID of event trigger(s).'
        )

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine

        utils.do_action_on_many(
            lambda s: mistral_client.event_triggers.delete(s),
            parsed_args.event_trigger_id,
            "Request to delete event trigger %s has been accepted.",
            "Unable to delete the specified event trigger(s)."
        )
