# Copyright 2020 The StackStorm Authors.
# Copyright 2019 Extreme Networks, Inc.
#
# 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 __future__ import absolute_import
import fnmatch

import eventlet

from kombu.mixins import ConsumerMixin
from oslo_config import cfg

from st2common.models.api.action import LiveActionAPI
from st2common.models.api.execution import ActionExecutionAPI
from st2common.models.api.execution import ActionExecutionOutputAPI
from st2common.transport import utils as transport_utils
from st2common.transport.queues import STREAM_ANNOUNCEMENT_WORK_QUEUE
from st2common.transport.queues import STREAM_EXECUTION_ALL_WORK_QUEUE
from st2common.transport.queues import STREAM_EXECUTION_UPDATE_WORK_QUEUE
from st2common.transport.queues import STREAM_LIVEACTION_WORK_QUEUE
from st2common.transport.queues import STREAM_EXECUTION_OUTPUT_QUEUE
from st2common import log as logging

__all__ = [
    "StreamListener",
    "ExecutionOutputListener",
    "get_listener",
    "get_listener_if_set",
]

LOG = logging.getLogger(__name__)


# Stores references to instantiated listeners
_stream_listener = None
_execution_output_listener = None


class BaseListener(ConsumerMixin):
    def __init__(self, connection):
        self.connection = connection
        self.queues = []
        self._stopped = False

    def get_consumers(self, consumer, channel):
        raise NotImplementedError("get_consumers() is not implemented")

    def processor(self, model=None):
        def process(body, message):
            meta = message.delivery_info
            event_name = "%s__%s" % (meta.get("exchange"), meta.get("routing_key"))

            try:
                if model:
                    body = model.from_model(
                        body, mask_secrets=cfg.CONF.api.mask_secrets
                    )

                self.emit(event_name, body)
            finally:
                message.ack()

        return process

    def emit(self, event, body):
        pack = (event, body)
        for queue in self.queues:
            queue.put(pack)

    def generator(
        self,
        events=None,
        action_refs=None,
        execution_ids=None,
        end_event=None,
        end_statuses=None,
        end_execution_id=None,
    ):
        queue = eventlet.Queue()
        queue.put("")
        self.queues.append(queue)
        try:
            stop = False