# Path: moira/api/request.py
# def delayed(f):
#     def decorator(resource, request):
#         @defer.inlineCallbacks
#         def wrapper():
#             try:
#                 yield f(resource, request)
#             except Exception as e:
#                 log.error("Error in delayed decorator wrapped function: {e}", e=e)
#                 request.setResponseCode(http.INTERNAL_SERVER_ERROR)
#                 request.finish()
#         wrapper()
#         return server.NOT_DONE_YET
#     return decorator
# 
# def check_json(f):
#     @defer.inlineCallbacks
#     def decorator(*args, **kwargs):
#         request = args[1]
#         try:
#             request.body = request.content.getvalue()
#             request.body_json = anyjson.deserialize(request.body)
#         except Exception as e:
#             log.error("Invalid trigger json [{json}]: {e}", json=request.body, e=e)
#             defer.returnValue(bad_request(request, "Content is not json"))
#         yield f(*args, **kwargs)
#     return decorator
# 
# Path: moira/api/resources/metric.py
# class Metrics(RedisResource):
# 
#     def __init__(self, db, trigger_id):
#         self.trigger_id = trigger_id
#         RedisResource.__init__(self, db)
# 
#     @delayed
#     @defer.inlineCallbacks
#     def render_GET(self, request):
#         json, trigger = yield self.db.getTrigger(self.trigger_id)
#         if json is None:
#             defer.returnValue(bad_request(request, "Trigger not found"))
#             raise StopIteration
# 
#         fromTime = request.args.get('from')[0]
#         endTime = request.args.get('to')[0]
#         context = createRequestContext(fromTime, endTime, allowRealTimeAlerting=True)
#         result = {}
#         for target in trigger.get("targets", [trigger.get("target")]):
#             time_series = yield evaluateTarget(context, target)
#             for time_serie in time_series:
#                 values = [(time_serie.start + time_serie.step * i, time_serie[i]) for i in range(0, len(time_serie))]
#                 result[time_serie.name] = [{"ts": ts, "value": value} for ts, value in values if value is not None]
#         self.write_json(request, result)
# 
#     @delayed
#     @defer.inlineCallbacks
#     def render_DELETE(self, request):
#         metric = request.args.get('name')[0]
# 
#         json, trigger = yield self.db.getTrigger(self.trigger_id)
# 
#         if json is None:
#             defer.returnValue(bad_request(request, "Trigger not found"))
#             raise StopIteration
# 
#         yield self.db.acquireTriggerCheckLock(self.trigger_id, 10)
# 
#         last_check = yield self.db.getTriggerLastCheck(self.trigger_id)
# 
#         if last_check is None:
#             defer.returnValue(bad_request(request, "Trigger check not found"))
#             raise StopIteration
# 
#         metrics = last_check.get('metrics', {})
#         if metric in metrics:
#             del last_check['metrics'][metric]
# 
#         for pattern in trigger.get("patterns"):
#             yield self.db.delPatternMetrics(pattern)
# 
#         yield self.db.setTriggerLastCheck(self.trigger_id, last_check)
#         yield self.db.delTriggerCheckLock(self.trigger_id)
# 
#         request.finish()
# 
# Path: moira/api/resources/redis.py
# class RedisResource(Resource):
# 
#     def __init__(self, db):
#         Resource.__init__(self)
#         self.db = db
# 
#     def write_json(self, request, result):
#         request.setHeader("Content-Type", "application/json")
#         request.write(anyjson.serialize(result))
#         request.finish()
# 
#     def write_dumped_json(self, request, result):
#         request.setHeader("Content-Type", "application/json")
#         request.write(str(result))
#         request.finish()
# 
#     @check_json
#     @check_trigger
#     @defer.inlineCallbacks
#     def save_trigger(self, request, trigger_id, message):
#         _, existing = yield self.db.getTrigger(trigger_id)
# 
#         yield self.db.acquireTriggerCheckLock(trigger_id, 10)
#         last_check = yield self.db.getTriggerLastCheck(trigger_id)
#         if last_check:
#             for metric in list(last_check.get('metrics', {})):
#                 if metric not in request.context['time_series_names']:
#                     del last_check['metrics'][metric]
#         else:
#             last_check = {
#                 "metrics": {},
#                 "state": state.NODATA,
#                 "score": 0
#             }
# 
#         yield self.db.setTriggerLastCheck(trigger_id, last_check)
# 
#         yield self.db.delTriggerCheckLock(trigger_id)
# 
#         yield self.db.saveTrigger(trigger_id, request.body_json,
#                                   request=request, existing=existing)
# 
#         self.write_json(request, {
#             "id": trigger_id,
#             "message": message
#         })


import uuid
from urllib import unquote
from twisted.internet import defer
from twisted.web import http
from moira.api.request import delayed, check_json
from moira.api.resources.metric import Metrics
from moira.api.resources.redis import RedisResource

class Triggers(RedisResource):

    def __init__(self, db):
        RedisResource.__init__(self, db)
        self.putChild("page", Page(db))

    def getChild(self, path, request):
        if not path:
            return self
        return Trigger(self.db, path)

    @delayed
    @defer.inlineCallbacks
    def render_GET(self, request):
        result = yield self.db.getTriggersChecks()
        self.write_json(request, {"list": result})

    @delayed
    @defer.inlineCallbacks
    def render_PUT(self, request):
        trigger_id = str(uuid.uuid4())
        yield self.save_trigger(request, trigger_id, "trigger created")


class Page(RedisResource):

    def __init__(self, db):
        RedisResource.__init__(self, db)


# Path: moira/api/request.py
# def delayed(f):
#     def decorator(resource, request):
#         @defer.inlineCallbacks
#         def wrapper():
#             try:
#                 yield f(resource, request)
#             except Exception as e:
#                 log.error("Error in delayed decorator wrapped function: {e}", e=e)
#                 request.setResponseCode(http.INTERNAL_SERVER_ERROR)
#                 request.finish()
#         wrapper()
#         return server.NOT_DONE_YET
#     return decorator
# 
# def check_json(f):
#     @defer.inlineCallbacks
#     def decorator(*args, **kwargs):
#         request = args[1]
#         try:
#             request.body = request.content.getvalue()
#             request.body_json = anyjson.deserialize(request.body)
#         except Exception as e:
#             log.error("Invalid trigger json [{json}]: {e}", json=request.body, e=e)
#             defer.returnValue(bad_request(request, "Content is not json"))
#         yield f(*args, **kwargs)
#     return decorator
# 
# Path: moira/api/resources/metric.py
# class Metrics(RedisResource):
# 
#     def __init__(self, db, trigger_id):
#         self.trigger_id = trigger_id
#         RedisResource.__init__(self, db)
# 
#     @delayed
#     @defer.inlineCallbacks
#     def render_GET(self, request):
#         json, trigger = yield self.db.getTrigger(self.trigger_id)
#         if json is None:
#             defer.returnValue(bad_request(request, "Trigger not found"))
#             raise StopIteration
# 
#         fromTime = request.args.get('from')[0]
#         endTime = request.args.get('to')[0]
#         context = createRequestContext(fromTime, endTime, allowRealTimeAlerting=True)
#         result = {}
#         for target in trigger.get("targets", [trigger.get("target")]):
#             time_series = yield evaluateTarget(context, target)
#             for time_serie in time_series:
#                 values = [(time_serie.start + time_serie.step * i, time_serie[i]) for i in range(0, len(time_serie))]
#                 result[time_serie.name] = [{"ts": ts, "value": value} for ts, value in values if value is not None]
#         self.write_json(request, result)
# 
#     @delayed
#     @defer.inlineCallbacks
#     def render_DELETE(self, request):
#         metric = request.args.get('name')[0]
# 
#         json, trigger = yield self.db.getTrigger(self.trigger_id)
# 
#         if json is None:
#             defer.returnValue(bad_request(request, "Trigger not found"))
#             raise StopIteration
# 
#         yield self.db.acquireTriggerCheckLock(self.trigger_id, 10)
# 
#         last_check = yield self.db.getTriggerLastCheck(self.trigger_id)
# 
#         if last_check is None:
#             defer.returnValue(bad_request(request, "Trigger check not found"))
#             raise StopIteration
# 
#         metrics = last_check.get('metrics', {})
#         if metric in metrics:
#             del last_check['metrics'][metric]
# 
#         for pattern in trigger.get("patterns"):
#             yield self.db.delPatternMetrics(pattern)
# 
#         yield self.db.setTriggerLastCheck(self.trigger_id, last_check)
#         yield self.db.delTriggerCheckLock(self.trigger_id)
# 
#         request.finish()
# 
# Path: moira/api/resources/redis.py
# class RedisResource(Resource):
# 
#     def __init__(self, db):
#         Resource.__init__(self)
#         self.db = db
# 
#     def write_json(self, request, result):
#         request.setHeader("Content-Type", "application/json")
#         request.write(anyjson.serialize(result))
#         request.finish()
# 
#     def write_dumped_json(self, request, result):
#         request.setHeader("Content-Type", "application/json")
#         request.write(str(result))
#         request.finish()
# 
#     @check_json
#     @check_trigger
#     @defer.inlineCallbacks
#     def save_trigger(self, request, trigger_id, message):
#         _, existing = yield self.db.getTrigger(trigger_id)
# 
#         yield self.db.acquireTriggerCheckLock(trigger_id, 10)
#         last_check = yield self.db.getTriggerLastCheck(trigger_id)
#         if last_check:
#             for metric in list(last_check.get('metrics', {})):
#                 if metric not in request.context['time_series_names']:
#                     del last_check['metrics'][metric]
#         else:
#             last_check = {
#                 "metrics": {},
#                 "state": state.NODATA,
#                 "score": 0
#             }
# 
#         yield self.db.setTriggerLastCheck(trigger_id, last_check)
# 
#         yield self.db.delTriggerCheckLock(trigger_id)
# 
#         yield self.db.saveTrigger(trigger_id, request.body_json,
#                                   request=request, existing=existing)
# 
#         self.write_json(request, {
#             "id": trigger_id,
#             "message": message
#         })


# Path: moira/api/resources/trigger.py
import uuid
from urllib import unquote
from twisted.internet import defer
from twisted.web import http
from moira.api.request import delayed, check_json
from moira.api.resources.metric import Metrics
from moira.api.resources.redis import RedisResource


class Triggers(RedisResource):

    def __init__(self, db):
        RedisResource.__init__(self, db)
        self.putChild("page", Page(db))

    def getChild(self, path, request):
        if not path:
            return self
        return Trigger(self.db, path)

    @delayed
    @defer.inlineCallbacks
    def render_GET(self, request):
        result = yield self.db.getTriggersChecks()
        self.write_json(request, {"list": result})

    @delayed
    @defer.inlineCallbacks
    def render_PUT(self, request):
        trigger_id = str(uuid.uuid4())
        yield self.save_trigger(request, trigger_id, "trigger created")


class Page(RedisResource):

    def __init__(self, db):
        RedisResource.__init__(self, db)


    @delayed