# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

import json

from st2common import log as logging
from st2common.util import reference
from st2reactor.rules.datatransform import get_transformer
from st2common.services import action as action_service
from st2common.models.db.action import LiveActionDB
from st2common.models.utils import action_param_utils
from st2common.constants.action import LIVEACTION_STATUS_SCHEDULED
from st2common.models.api.access import get_system_username


LOG = logging.getLogger('st2reactor.ruleenforcement.enforce')


class RuleEnforcer(object):
    def __init__(self, trigger_instance, rule):
        self.trigger_instance = trigger_instance
        self.rule = rule
        self.data_transformer = get_transformer(trigger_instance.payload)

    def enforce(self):
        data = self.data_transformer(self.rule.action.parameters)
        LOG.info('Invoking action %s for trigger_instance %s with data %s.',
                 self.rule.action.ref, self.trigger_instance.id,
                 json.dumps(data))
        context = {
            'trigger_instance': reference.get_ref_from_model(self.trigger_instance),
            'rule': reference.get_ref_from_model(self.rule),
            'user': get_system_username()
        }

        liveaction = RuleEnforcer._invoke_action(self.rule.action, data, context)
        if not liveaction:
            extra = {'trigger_instance': self.trigger_instance, 'rule': self.rule}
            LOG.audit('Rule enforcement failed. Liveaction for Action %s failed. '
                      'TriggerInstance: %s and Rule: %s',
                      self.rule.action.name, self.trigger_instance, self.rule,
                      extra=extra)
            return None

        liveaction_id = liveaction.get('id', None)
        extra = {'trigger_instance': self.trigger_instance, 'rule': self.rule,
                 'liveaction': liveaction}
        LOG.audit('Rule enforced. Liveaction %s, TriggerInstance %s and Rule %s.',
                  liveaction_id, self.trigger_instance, self.rule, extra=extra)

        return liveaction_id

    @staticmethod
    def _invoke_action(action, params, context=None):
        action_ref = action['ref']
        # prior to shipping off the params cast them to the right type.
        params = action_param_utils.cast_params(action_ref, params)
        liveaction = LiveActionDB(action=action_ref, context=context, parameters=params)
        liveaction, _ = action_service.schedule(liveaction)
        return ({'id': str(liveaction.id)}
                if liveaction.status == LIVEACTION_STATUS_SCHEDULED else None)

@@ -2002,16 +2002,19 @@
 veaction
+_db
  = RuleE
@@ -2094,16 +2094,19 @@
 veaction
+_db
 :%0A      
@@ -2466,59 +2466,8 @@
 ne%0A%0A
-        liveaction_id = liveaction.get('id', None)%0A
     
@@ -2582,16 +2582,19 @@
 veaction
+_db
 %7D%0A      
@@ -2699,18 +2699,18 @@
 eaction_
-i
 d
+b
 , self.t
@@ -2777,18 +2777,18 @@
 eaction_
-i
 d
+b
 %0A%0A    @s
@@ -2849,24 +2849,168 @@
 text=None):%0A
+        %22%22%22%0A        Schedule an action execution.%0A%0A        :rtype: :class:%60LiveActionDB%60 on successful schedueling, None otherwise.%0A        %22%22%22%0A
         acti
@@ -3032,16 +3032,17 @@
 %5B'ref'%5D%0A
+%0A
         
@@ -3326,59 +3326,9 @@
 on)%0A
-        return (%7B'id': str(liveaction.id)%7D%0A        
+%0A
     
@@ -3386,16 +3386,74 @@
 ULED
- else
+:%0A            return liveaction%0A        else:%0A            return
  None
-)
 %0A

Update enforce and _invoke_action method to return LiveActionDB object and get rid of this weird dict with id key.