import sentry_sdk
from flask import Flask, jsonify, request, g
from webargs import fields, validate
from webargs.flaskparser import use_args
from util import util
import files
import accounts
import passwords

sentry_sdk.init(
    dsn="https://6a7be9c67251f0b715d7d477c5ae2cef@o4508066290532352.ingest.de.sentry.io/4508070957875280",
    traces_sample_rate=1.0,
    profiles_sample_rate=1.0,
)

app = Flask(__name__)

# Error handlers


@app.errorhandler(404)
def handle_404(e):
    return jsonify({"message": "Resource not found"}), 404


@app.errorhandler(422)
def handle_unprocessable_entity(e):
    return jsonify(
        {
            "validations": e.data.get("messages"),
        }
    ), 422


@app.errorhandler(429)
def handle_429(e):
    return jsonify(
        {"message": "Rate limit exceeded", "Allowed limit": e.description}
    ), 429


@app.errorhandler(500)
def handle_500():
    return jsonify(
        {"message": "There was a problem with this request. Please try again later."}
    ), 500


# Route handlers


@app.route("/accounts", methods=["POST"])
@use_args(
    {
        "email": fields.Email(required=True),
        "password": fields.Str(required=True, validate=validate.Length(min=8)),
    }
)
def accounts_route(args):
    return accounts.create(args)


@app.route("/accounts/password/tokens", methods=["POST"])
def password_tokens_route():
    return passwords.create_reset_token()


@app.route("/accounts/password/tokens", methods=["PUT"])
@use_args({"password": fields.Str(), "token": fields.Str()})
def password_tokens_route_put(args):
    return passwords.update(args)


@app.route("/accounts/password", methods=["PUT"])
@use_args(
    {
        "currentPassword": fields.Str(required=True),
        "password": fields.Str(required=True, validate=validate.Length(min=8)),
    }
)
@util.auth
def password_route_put(args):
    return passwords.update(args, user=g.user)


@app.route("/tokens", methods=["POST"])
@use_args({"email": fields.Email(required=True), "password": fields.Str(required=True)})
def tokens_post_route(args):
    return accounts.login(args)


@app.route("/tokens", methods=["DELETE"])
@util.auth
def tokens_delete_route():
    if request.method == "DELETE":
        return accounts.logout(g.user)


@app.route("/tokens/all", methods=["DELETE"])
@util.auth
def tokens_all_delete_route():
    if request.method == "DELETE":
        return accounts.logout_all(g.user)


@app.route("/files", methods=["POST", "GET"])
@util.auth
def files_route():
    if request.method == "POST":
        return files.create(g.user)
    if request.method == "GET":
        return files.get(g.user)


@app.route("/files/<key>", methods=["PUT", "GET", "DELETE"])
@util.auth
def file_route(key):
    if request.method == "PUT":
        return files.update_file(g.user, key)
    if request.method == "GET":
        return files.get_file(g.user, key)
    if request.method == "DELETE":
        return files.delete_file(g.user, key)
