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

[((9, 18, 9, 42), 'main.server.models.MessageSchema', 'MessageSchema', (), '', False, 'from main.server.models import Message, MessageSchema\n'), ((10, 17, 10, 32), 'main.server.models.MessageSchema', 'MessageSchema', ({}, {}), '()', False, 'from main.server.models import Message, MessageSchema\n'), ((24, 5, 24, 30), 'main.server.cache.cached', 'cache.cached', (), '', False, 'from main.server import app, cache, db\n'), ((31, 5, 31, 30), 'main.server.cache.cached', 'cache.cached', (), '', False, 'from main.server import app, cache, db\n'), ((53, 5, 53, 30), 'main.server.cache.cached', 'cache.cached', (), '', False, 'from main.server import app, cache, db\n'), ((64, 5, 64, 19), 'flask_jwt.jwt_required', 'jwt_required', ({}, {}), '()', False, 'from flask_jwt import jwt_required\n'), ((96, 5, 96, 30), 'main.server.cache.cached', 'cache.cached', (), '', False, 'from main.server import app, cache, db\n'), ((107, 5, 107, 19), 'flask_jwt.jwt_required', 'jwt_required', ({}, {}), '()', False, 'from flask_jwt import jwt_required\n'), ((56, 19, 56, 38), 'main.server.models.Message.query.all', 'Message.query.all', ({}, {}), '()', False, 'from main.server.models import Message, MessageSchema\n'), ((67, 20, 67, 48), 'flask.request.get_json', 'request.get_json', (), '', False, 'from flask import request\n'), ((89, 8, 89, 31), 'main.server.db.session.add', 'db.session.add', ({(89, 23, 89, 30): 'message'}, {}), '(message)', False, 'from main.server import app, cache, db\n'), ((90, 8, 90, 27), 'main.server.db.session.commit', 'db.session.commit', ({}, {}), '()', False, 'from main.server import app, cache, db\n'), ((99, 18, 99, 62), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', (), '', False, 'from main.server.models import Message, MessageSchema\n'), ((111, 18, 111, 62), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', (), '', False, 'from main.server.models import Message, MessageSchema\n'), ((117, 8, 117, 27), 'main.server.db.session.commit', 'db.session.commit', ({}, {}), '()', False, 'from main.server import app, cache, db\n'), ((27, 46, 27, 67), 'main.server.models.Message.query.count', 'Message.query.count', ({}, {}), '()', False, 'from main.server.models import Message, MessageSchema\n'), ((47, 15, 47, 55), 'main.server.models.Message.query.filter_by', 'Message.query.filter_by', (), '', False, 'from main.server.models import Message, MessageSchema\n')]