''' 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')
[((2986, 3050), 'src.api.add_resource', 'api.add_resource', (['UserLoginResource', '"""/login/"""'], {'endpoint': '"""login"""'}), "(UserLoginResource, '/login/', endpoint='login')\n", (3002, 3050), False, 'from src import db, api\n'), ((3051, 3124), 'src.api.add_resource', 'api.add_resource', (['UserRegisterResource', '"""/register/"""'], {'endpoint': '"""register"""'}), "(UserRegisterResource, '/register/', endpoint='register')\n", (3067, 3124), False, 'from src import db, api\n'), ((2513, 2532), 'datetime.timedelta', 'timedelta', ([], {'days': '(365)'}), '(days=365)\n', (2522, 2532), False, 'from datetime import timedelta\n'), ((557, 586), 'flask.render_template', 'render_template', (['"""login.html"""'], {}), "('login.html')\n", (572, 586), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2258, 2278), 'src.db.session.add', 'db.session.add', (['user'], {}), '(user)\n', (2272, 2278), False, 'from src import db, api\n'), ((2291, 2310), 'src.db.session.commit', 'db.session.commit', ([], {}), '()\n', (2308, 2310), False, 'from src import db, api\n'), ((854, 873), 'datetime.timedelta', 'timedelta', ([], {'days': '(365)'}), '(days=365)\n', (863, 873), False, 'from datetime import timedelta\n'), ((1507, 1523), 'flask_login.login_user', 'login_user', (['user'], {}), '(user)\n', (1517, 1523), False, 'from flask_login import login_user, current_user\n'), ((1859, 1888), 'flask.jsonify', 'jsonify', (["{'error': 'No data'}"], {}), "({'error': 'No data'})\n", (1866, 1888), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2015, 2056), 'flask.jsonify', 'jsonify', (["{'error': 'User already exists'}"], {}), "({'error': 'User already exists'})\n", (2022, 2056), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2163, 2178), 'flask.jsonify', 'jsonify', (['errors'], {}), '(errors)\n', (2170, 2178), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2403, 2424), 'src.db.session.rollback', 'db.session.rollback', ([], {}), '()\n', (2422, 2424), False, 'from src import db, api\n'), ((1217, 1289), 'flask.jsonify', 'jsonify', (["{'error': {'code': 400, 'msg': 'No such user/wrong password.'}}"], {}), "({'error': {'code': 400, 'msg': 'No such user/wrong password.'}})\n", (1224, 1289), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((1562, 1586), 'flask.redirect', 'redirect', (['"""/admin/"""', '(302)'], {}), "('/admin/', 302)\n", (1570, 1586), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((1643, 1673), 'flask.redirect', 'redirect', (['"""/api/v1/login"""', '(403)'], {}), "('/api/v1/login', 403)\n", (1651, 1673), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2458, 2486), 'flask.jsonify', 'jsonify', ([], {'error': "{'code': 400}"}), "(error={'code': 400})\n", (2465, 2486), False, 'from flask import request, jsonify, make_response, redirect, json, render_template\n'), ((2755, 2815), 'flask_jwt_extended.create_access_token', 'create_access_token', ([], {'identity': 'user.id', 'expires_delta': 'expires'}), '(identity=user.id, expires_delta=expires)\n', (2774, 2815), False, 'from flask_jwt_extended import create_access_token, jwt_required\n'), ((1090, 1153), 'flask_jwt_extended.create_access_token', 'create_access_token', ([], {'identity': "user['id']", 'expires_delta': 'expires'}), "(identity=user['id'], expires_delta=expires)\n", (1109, 1153), False, 'from flask_jwt_extended import create_access_token, jwt_required\n')]