from flask import request
from flask_jwt import jwt_required

from flask_restful import Resource

from main.server import app, cache, db
from main.server.models import Message, MessageSchema

messages_schema = MessageSchema(many=True)
message_schema = MessageSchema()


@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST'
    response.headers[
        'Access-Control-Allow-Headers'] = 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'
    return response


class MessageCount(Resource):
    @cache.cached(timeout=100)
    def get(self):
        """Gets the number of messages available on the server"""
        return {'status': 'success', 'count': Message.query.count()}, 200


class MessageListRangeResource(Resource):
    @cache.cached(timeout=100)
    def get(self, lower, upper):
        """Gets a range of messages on the server"""
        if int(lower) < 1:
            return {'status': 'fail', 'messages': 'Invalid index: ' + str(lower)}, 400
        if int(lower) > int(upper):
            return {'status': 'fail',
                    'messages': 'Upper range cannot be less than lower range: ' + str(lower) + '>' + str(upper)}, 400
        messages = Message.query.filter(Message.messageID >= int(lower)).filter(Message.messageID <= int(upper))

        if not messages:
            return {'status': 'fail',
                    'messages': 'Out of range: ' + str(lower) + ' - ' + str(upper) + ' does not exist'}, 404

        messages = messages_schema.dump(messages)

        if not Message.query.filter_by(messageID=upper).first():  # the last item in the range
            return {'status': 'success', 'messages': messages}, 206  # Partial Content Served
        return {'status': 'success', 'messages': messages}, 200


class MessageListResource(Resource):
    @cache.cached(timeout=100)
    def get(self):
        """Gets all messages on the server"""
        messages = Message.query.all()
        messages = messages_schema.dump(messages)

        if not messages:
            return {'status': 'success', 'messages': messages}, 206  # Partial Content Served

        return {'status': 'success', 'messages': messages}, 200

    @jwt_required()
    def post(self):
        """Add message"""
        json_data = request.get_json(force=True)

        if not json_data:
            return {'status': 'fail', 'message': 'No input data'}, 400

        errors = message_schema.validate(json_data)

        if errors:
            return {'status': 'fail', 'message': 'Error handling request'}, 422

        data = message_schema.load(json_data)

        message = Message.query.filter_by(orig_msg=data.get('orig_msg')).first()

        if message:
            return {'status': 'fail', 'message': 'Message already exists'}, 400

        message = Message(orig_msg=data.get('orig_msg'),
                          tl_msg=data.get('tl_msg'),
                          country=data.get('country'),
                          username=data.get('username'))

        db.session.add(message)
        db.session.commit()

        return {'status': 'success', 'message': 'Message successfully created'}, 201


class MessageResource(Resource):
    @cache.cached(timeout=100)
    def get(self, messageID):
        """"Get a message by message ID"""
        message = Message.query.filter_by(messageID=messageID)

        if not message.first():
            return {'status': 'fail', 'message': 'No message with ID ' + str(messageID) + ' exists'}, 404

        message = messages_schema.dump(message)
        return {'status': 'success', 'messages': message}, 200

    @jwt_required()
    def delete(self, messageID):
        """delete a message by ID"""

        message = Message.query.filter_by(messageID=messageID)

        if not message.first():
            return {'status': 'fail', 'message': 'No message with ID ' + str(messageID) + ' exists'}, 404

        message.delete()
        db.session.commit()
        return {'status': 'sucess', 'message': 'Message Deleted'}, 200

[((210, 234), 'main.server.models.MessageSchema', 'MessageSchema', ([], {'many': '(True)'}), '(many=True)\n', (223, 234), False, 'from main.server.models import Message, MessageSchema\n'), ((252, 267), 'main.server.models.MessageSchema', 'MessageSchema', ([], {}), '()\n', (265, 267), False, 'from main.server.models import Message, MessageSchema\n'), ((768, 793), 'main.server.cache.cached', 'cache.cached', ([], {'timeout': '(100)'}), '(timeout=100)\n', (780, 793), False, 'from main.server import app, cache, db\n'), ((1002, 1027), 'main.server.cache.cached', 'cache.cached', ([], {'timeout': '(100)'}), '(timeout=100)\n', (1014, 1027), False, 'from main.server import app, cache, db\n'), ((2055, 2080), 'main.server.cache.cached', 'cache.cached', ([], {'timeout': '(100)'}), '(timeout=100)\n', (2067, 2080), False, 'from main.server import app, cache, db\n'), ((2426, 2440), 'flask_jwt.jwt_required', 'jwt_required', ([], {}), '()\n', (2438, 2440), False, 'from flask_jwt import jwt_required\n'), ((3427, 3452), 'main.server.cache.cached', 'cache.cached', ([], {'timeout': '(100)'}), '(timeout=100)\n', (3439, 3452), False, 'from main.server import app, cache, db\n'), ((3846, 3860), 'flask_jwt.jwt_required', 'jwt_required', ([], {}), '()\n', (3858, 3860), False, 'from flask_jwt import jwt_required\n'), ((2165, 2184), 'main.server.models.Message.query.all', 'Message.query.all', ([], {}), '()\n', (2182, 2184), False, 'from main.server.models import Message, MessageSchema\n'), ((2507, 2535), 'flask.request.get_json', 'request.get_json', ([], {'force': '(True)'}), '(force=True)\n', (2523, 2535), False, 'from flask import request\n'), ((3249, 3272), 'main.server.db.session.add', 'db.session.add', (['message'], {}), '(message)\n', (3263, 3272), False, 'from main.server import app, cache, db\n'), ((3281, 3300), 'main.server.db.session.commit', 'db.session.commit', ([], {}), '()\n', (3298, 3300), False, 'from main.server import app, cache, db\n'), ((3544, 3588), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', ([], {'messageID': 'messageID'}), '(messageID=messageID)\n', (3567, 3588), False, 'from main.server.models import Message, MessageSchema\n'), ((3950, 3994), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', ([], {'messageID': 'messageID'}), '(messageID=messageID)\n', (3973, 3994), False, 'from main.server.models import Message, MessageSchema\n'), ((4168, 4187), 'main.server.db.session.commit', 'db.session.commit', ([], {}), '()\n', (4185, 4187), False, 'from main.server import app, cache, db\n'), ((925, 946), 'main.server.models.Message.query.count', 'Message.query.count', ([], {}), '()\n', (944, 946), False, 'from main.server.models import Message, MessageSchema\n'), ((1773, 1813), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', ([], {'messageID': 'upper'}), '(messageID=upper)\n', (1796, 1813), False, 'from main.server.models import Message, MessageSchema\n')]