''' User views '''

from datetime import timedelta
from flask import request, jsonify, make_response, redirect, json, render_template
from flask_jwt_extended import (create_access_token, jwt_required)
from flask_restful import Resource
from flask_login import login_user, current_user
from sqlalchemy.exc import IntegrityError, InvalidRequestError

from src import db, api

from .models import User
from .schemas import UserSchema

class UserLoginResource(Resource):
    model = User
    schema = UserSchema

    def get(self):
        return make_response(render_template('login.html'))

    def post(self):

        if request.json:
            data = request.json
            user = self.model.query.filter(self.model.email == data['email']).first()
            if user and self.model.check_password(user, data['password']):
                expires = timedelta(days=365)
                user = UserSchema(only=('id', 'email', 'is_admin')).dump(user).data
                return make_response(
                    jsonify({'id': user,
                             'authentication_token': create_access_token(identity=user['id'], expires_delta=expires)}), 200)
            else:
                return make_response(jsonify({"error": {"code": 400, "msg": "No such user/wrong password."}}), 400)

        else:
            data = request.form
            user = self.model.query.filter(self.model.email == data['email']).first()
            if user and self.model.check_password(user, data['password']) and login_user(user):
                return make_response(redirect('/admin/', 302))
            else:
                return make_response(redirect('/api/v1/login', 403))


class UserRegisterResource(Resource):
    model = User
    schema = UserSchema

    def post(self):
        data = request.json
        if not data:
            return make_response(jsonify({'error': 'No data'}), 400)
        user = User.query.filter(User.email == data['email']).first()
        if user:
            return make_response(jsonify({'error': 'User already exists'}), 403)
        user, errors = self.schema().load(data)
        if errors:
            return make_response(jsonify(errors), 400)
        try:
            user.set_password(data['password'])
            db.session.add(user)
            db.session.commit()
        except (IntegrityError, InvalidRequestError) as e:
            print(e)
            db.session.rollback()
            return make_response(jsonify(error={'code': 400 }), 400)

        expires = timedelta(days=365)
        return make_response(
            jsonify(created_user={'id': user.id,
                        'user': self.schema(only=('id', 'email', 'is_admin')).dump(user).data,
                        'authentication_token': create_access_token(identity=user.id,
                                                                                expires_delta=expires)}), 200)

                                                                                
api.add_resource(UserLoginResource, '/login/', endpoint='login')
api.add_resource(UserRegisterResource, '/register/', endpoint='register')
[((76, 0, 76, 64), 'src.api.add_resource', 'api.add_resource', (), '', False, 'from src import db, api\n'), ((77, 0, 77, 73), 'src.api.add_resource', 'api.add_resource', (), '', False, 'from src import db, api\n'), ((68, 18, 68, 37), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import timedelta\n'), ((20, 29, 20, 58), 'flask.render_template', 'render_template', ({(20, 45, 20, 57): '"""login.html"""'}, {}), "('login.html')", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((61, 12, 61, 32), 'src.db.session.add', 'db.session.add', ({(61, 27, 61, 31): 'user'}, {}), '(user)', False, 'from src import db, api\n'), ((62, 12, 62, 31), 'src.db.session.commit', 'db.session.commit', ({}, {}), '()', False, 'from src import db, api\n'), ((28, 26, 28, 45), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import timedelta\n'), ((39, 78, 39, 94), 'flask_login.login_user', 'login_user', ({(39, 89, 39, 93): 'user'}, {}), '(user)', False, 'from flask_login import login_user, current_user\n'), ((52, 33, 52, 62), 'flask.jsonify', 'jsonify', ({(52, 41, 52, 61): "{'error': 'No data'}"}, {}), "({'error': 'No data'})", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((55, 33, 55, 74), 'flask.jsonify', 'jsonify', ({(55, 41, 55, 73): "{'error': 'User already exists'}"}, {}), "({'error': 'User already exists'})", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((58, 33, 58, 48), 'flask.jsonify', 'jsonify', ({(58, 41, 58, 47): 'errors'}, {}), '(errors)', False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((65, 12, 65, 33), 'src.db.session.rollback', 'db.session.rollback', ({}, {}), '()', False, 'from src import db, api\n'), ((34, 37, 34, 109), 'flask.jsonify', 'jsonify', ({(34, 45, 34, 108): "{'error': {'code': 400, 'msg': 'No such user/wrong password.'}}"}, {}), "({'error': {'code': 400, 'msg': 'No such user/wrong password.'}})", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((40, 37, 40, 61), 'flask.redirect', 'redirect', ({(40, 46, 40, 55): '"""/admin/"""', (40, 57, 40, 60): '(302)'}, {}), "('/admin/', 302)", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((42, 37, 42, 67), 'flask.redirect', 'redirect', ({(42, 46, 42, 61): '"""/api/v1/login"""', (42, 63, 42, 66): '(403)'}, {}), "('/api/v1/login', 403)", False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((66, 33, 66, 62), 'flask.jsonify', 'jsonify', (), '', False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((72, 48, 73, 102), 'flask_jwt_extended.create_access_token', 'create_access_token', (), '', False, 'from flask_jwt_extended import create_access_token, jwt_required\n'), ((32, 53, 32, 116), 'flask_jwt_extended.create_access_token', 'create_access_token', (), '', False, 'from flask_jwt_extended import create_access_token, jwt_required\n')]