# Path: chaosmonkey/api/hal.py
# class HAL(object):
#     """Enables Flask-HAL integration into Flask Applications, either by the
#     Application Factory Pattern or directly into an already created Flask
#     Application instance.
# 
#     This will set a custom ``response_class`` for the Application which
#     handles the conversion of a ``HAL`` document response from a
#     view into it's ``JSON`` representation.
#     """
# 
#     def __init__(self, app=None, response_class=None):
#         """Initialise Flask-HAL with a Flask Application. Acts as a proxy
#         to :meth:`chaosmonkey.api.hal.HAL.init_app`.
# 
#         Example:
#             >>> from flask import Flask
#             >>> from chaosmonkey.api.hal import HAL
#             >>> app = Flask(__name__)
#             >>> HAL(app=app)
# 
#         Keyword Args:
#             app (flask.app.Flask): Optional Flask application instance
#             response_class (class): Optional custom ``response_class``
#         """
# 
#         if app is not None:
#             self.init_app(app, response_class=response_class)
# 
#     def init_app(self, app, response_class=None):
#         """Initialise Flask-HAL with a Flask Application. This is designed to
#         be used with the Flask Application Factory Pattern.
# 
#         Example:
#             >>> from flask import Flask
#             >>> from chaosmonkey.api.hal import HAL
#             >>> app = Flask(__name__)
#             >>> HAL().init_app(app)
# 
#         Args:
#             app (flask.app.Flask): Flask application instance
# 
#         Keyword Args:
#             response_class (class): Optional custom ``response_class``
#         """
# 
#         # Set the response class
#         if response_class is None:
#             app.response_class = HALResponse
#         else:
#             app.response_class = response_class
# 
# class HALResponse(Response):
#     """A custom response class which overrides the default Response class
#     wrapper.
# 
#     Example:
#         >>> from flask import Flask()
#         >>> from chaosmonkey.api.hal import HALResponse
#         >>> app = Flask(__name__)
#         >>> app.response_class = HALResponse
#     """
# 
#     @staticmethod
#     def force_type(rv, env):
#         """Called by ``flask.make_response`` when a view returns a none byte,
#         string or unicode value. This method takes the views return value
#         and converts into a standard `Response`.
# 
#         Args:
#             rv (chaosmonkey.api.hal.document.Document): View return value
#             env (dict): Request environment
# 
#         Returns:
#             flask.wrappers.Response: A standard Flask response
#         """
# 
#         if isinstance(rv, Document):
#             return Response(
#                 rv.to_json(),
#                 headers={
#                     'Content-Type': 'application/hal+json'
#                 })
# 
#         return Response.force_type(rv, env)
# 
# Path: chaosmonkey/api/attacks_blueprint.py
# def list_attacks():
# 
# Path: chaosmonkey/api/executors_blueprint.py
# def get_executors():
# def put_executor(executor_id):
# def delete_executor(executor_id):
# def trigger_to_dict(trigger):
# def dict_to_trigger(trigger_dict):
# 
# Path: chaosmonkey/api/planners_blueprint.py
# def list_planners():
# 
# Path: chaosmonkey/api/plans_blueprint.py
# def add_plan():
# def list_plans():
# def get_plan(plan_id):
# def delete_plan(plan_id):
# 
# Path: chaosmonkey/api/api_errors.py
# class APIError(Exception):
#     """
#     Represents an API Error
# 
#     :param message: message to be returned to the user
#     :param status_code: response status code (defaults to 400)
#     :param payload: custom payload to give extra info in the response
# 
#     Example:
#             >>> raise APIError("Error detected", 500, {"extra": "extra_info"})
# 
#     """
# 
#     def __init__(self, message, status_code=None, payload=None):
#         Exception.__init__(self)
#         self.message = message
#         self.status_code = status_code or 400
#         self.payload = payload
# 
#     def to_dict(self):
#         """Convert exception to dict"""
#         dict_ = dict(self.payload or ())
#         dict_['msg'] = self.message
#         return dict_
# 
#     def __str__(self):
#         return '[%d] %s' % (self.status_code, self.message)


import logging
from flask_cors import CORS
from flask import Flask, json
from chaosmonkey.api.hal import HAL, HALResponse
from chaosmonkey.api.attacks_blueprint import attacks
from chaosmonkey.api.executors_blueprint import executors
from chaosmonkey.api.planners_blueprint import planners
from chaosmonkey.api.plans_blueprint import plans
from chaosmonkey.api.api_errors import APIError

log = logging.getLogger(__name__)

# Create FlaskApp
flask_app = Flask("cm_api")
HAL(flask_app, HALResponse)
CORS(flask_app)

# Register blueprints
root = "/api/"
prev1 = root + "1"
flask_app.register_blueprint(executors, url_prefix=prev1 + "/executors")
flask_app.register_blueprint(plans, url_prefix=prev1 + "/plans")
flask_app.register_blueprint(attacks, url_prefix=prev1 + "/attacks")
flask_app.register_blueprint(planners, url_prefix=prev1 + "/planners")


# Register error handler for custom APIError exception
@flask_app.errorhandler(APIError)

# Path: chaosmonkey/api/hal.py
# class HAL(object):
#     """Enables Flask-HAL integration into Flask Applications, either by the
#     Application Factory Pattern or directly into an already created Flask
#     Application instance.
# 
#     This will set a custom ``response_class`` for the Application which
#     handles the conversion of a ``HAL`` document response from a
#     view into it's ``JSON`` representation.
#     """
# 
#     def __init__(self, app=None, response_class=None):
#         """Initialise Flask-HAL with a Flask Application. Acts as a proxy
#         to :meth:`chaosmonkey.api.hal.HAL.init_app`.
# 
#         Example:
#             >>> from flask import Flask
#             >>> from chaosmonkey.api.hal import HAL
#             >>> app = Flask(__name__)
#             >>> HAL(app=app)
# 
#         Keyword Args:
#             app (flask.app.Flask): Optional Flask application instance
#             response_class (class): Optional custom ``response_class``
#         """
# 
#         if app is not None:
#             self.init_app(app, response_class=response_class)
# 
#     def init_app(self, app, response_class=None):
#         """Initialise Flask-HAL with a Flask Application. This is designed to
#         be used with the Flask Application Factory Pattern.
# 
#         Example:
#             >>> from flask import Flask
#             >>> from chaosmonkey.api.hal import HAL
#             >>> app = Flask(__name__)
#             >>> HAL().init_app(app)
# 
#         Args:
#             app (flask.app.Flask): Flask application instance
# 
#         Keyword Args:
#             response_class (class): Optional custom ``response_class``
#         """
# 
#         # Set the response class
#         if response_class is None:
#             app.response_class = HALResponse
#         else:
#             app.response_class = response_class
# 
# class HALResponse(Response):
#     """A custom response class which overrides the default Response class
#     wrapper.
# 
#     Example:
#         >>> from flask import Flask()
#         >>> from chaosmonkey.api.hal import HALResponse
#         >>> app = Flask(__name__)
#         >>> app.response_class = HALResponse
#     """
# 
#     @staticmethod
#     def force_type(rv, env):
#         """Called by ``flask.make_response`` when a view returns a none byte,
#         string or unicode value. This method takes the views return value
#         and converts into a standard `Response`.
# 
#         Args:
#             rv (chaosmonkey.api.hal.document.Document): View return value
#             env (dict): Request environment
# 
#         Returns:
#             flask.wrappers.Response: A standard Flask response
#         """
# 
#         if isinstance(rv, Document):
#             return Response(
#                 rv.to_json(),
#                 headers={
#                     'Content-Type': 'application/hal+json'
#                 })
# 
#         return Response.force_type(rv, env)
# 
# Path: chaosmonkey/api/attacks_blueprint.py
# def list_attacks():
# 
# Path: chaosmonkey/api/executors_blueprint.py
# def get_executors():
# def put_executor(executor_id):
# def delete_executor(executor_id):
# def trigger_to_dict(trigger):
# def dict_to_trigger(trigger_dict):
# 
# Path: chaosmonkey/api/planners_blueprint.py
# def list_planners():
# 
# Path: chaosmonkey/api/plans_blueprint.py
# def add_plan():
# def list_plans():
# def get_plan(plan_id):
# def delete_plan(plan_id):
# 
# Path: chaosmonkey/api/api_errors.py
# class APIError(Exception):
#     """
#     Represents an API Error
# 
#     :param message: message to be returned to the user
#     :param status_code: response status code (defaults to 400)
#     :param payload: custom payload to give extra info in the response
# 
#     Example:
#             >>> raise APIError("Error detected", 500, {"extra": "extra_info"})
# 
#     """
# 
#     def __init__(self, message, status_code=None, payload=None):
#         Exception.__init__(self)
#         self.message = message
#         self.status_code = status_code or 400
#         self.payload = payload
# 
#     def to_dict(self):
#         """Convert exception to dict"""
#         dict_ = dict(self.payload or ())
#         dict_['msg'] = self.message
#         return dict_
# 
#     def __str__(self):
#         return '[%d] %s' % (self.status_code, self.message)


# Path: chaosmonkey/api/app.py
import logging
from flask_cors import CORS
from flask import Flask, json
from chaosmonkey.api.hal import HAL, HALResponse
from chaosmonkey.api.attacks_blueprint import attacks
from chaosmonkey.api.executors_blueprint import executors
from chaosmonkey.api.planners_blueprint import planners
from chaosmonkey.api.plans_blueprint import plans
from chaosmonkey.api.api_errors import APIError


log = logging.getLogger(__name__)

# Create FlaskApp
flask_app = Flask("cm_api")
HAL(flask_app, HALResponse)
CORS(flask_app)

# Register blueprints
root = "/api/"
prev1 = root + "1"
flask_app.register_blueprint(executors, url_prefix=prev1 + "/executors")
flask_app.register_blueprint(plans, url_prefix=prev1 + "/plans")
flask_app.register_blueprint(attacks, url_prefix=prev1 + "/attacks")
flask_app.register_blueprint(planners, url_prefix=prev1 + "/planners")


# Register error handler for custom APIError exception
@flask_app.errorhandler(APIError)

def handle_invalid_usage(error):